1. 程式人生 > >【ElasticSearch】(七)淺析search_after 及 from&size,scroll,search_after效能分析

【ElasticSearch】(七)淺析search_after 及 from&size,scroll,search_after效能分析

一、"search_after"是什麼?

     “search_after”是用於查詢的dsl,可以起到類似"from & size"分頁作用的結構化查詢,程式碼展示如下:

GET twitter/_search
{
    "size": 10,
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    },
    "search_after": [1000],
    "sort": [
        {"date": "asc"},
        {"tie_breaker_id": "asc"}
    ]
}

        上述語句的含義在於,查詢第1000~1010條語句,可以看做另外一種from size分頁。

 

二、為什麼使用“search_after”?

      參看之前的文章,分頁查詢通過from & size,scroll 都可以實現。但是這兩種方式都有各自的弊端,比如“Pagination of results can be done by using the from and size but the cost becomes prohibitive when the deep pagination is reached. The index.max_result_window

 which defaults to 10,000 is a safeguard, search requests take heap memory and time proportional to from + size. The Scroll api is recommended for efficient deep scrolling but scroll contexts are costly and it is not recommended to use it for real time user requests. ”

       可歸納為亮點:

       1、from size,深度分頁或者size特別大的情況,會出deep pagination問題;且es的自保機制max_result_window也會阻預設的查詢。

       2、scroll雖然能夠解決from size帶來的問題,但是由於它代表的是某個時刻的snapshot,不適合做實時查詢;且由於scroll後接超時時間,頻繁地發起scroll請求,也會出現一系列問題。

      此時,search_after恰巧能夠解決scroll的非實時取值問題。

 

三、form&size / scroll / search_after 效能比較

      假設執行如下查詢:

GET twitter/_search
{
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    }
}

      分別分頁獲取【1 - 10】【49000 - 49010】【 99000 - 99010】範圍各10條資料(前提10w條),效能大致是這樣:

es分頁效能對比表
分頁方式 1~10 49000~49010 99000~99010
form…size 8ms 30ms 117ms
scroll 7ms 66ms 36ms
search_after 5ms 8ms 7ms

 

      note:該資料並非博主本人測試,是公司wiki裡負責es的同事的實驗結果。

      由此可知,超級深的分頁,使用search_after最為合適了,from&size方式,列表查詢已經夠了(一般人的操作部分檢視第20頁之後的資料),匯出列表可以使用scroll。

      對於三者的原理:

       (1) from / size : 該查詢的實現原理類似於mysql中的limit,比如查詢第10001條資料,那麼需要將前面的10000條都拿出來,進行過濾,最終才得到資料。(效能較差,實現簡單,適用於少量資料,資料量不超過10w)。
       (2) scroll:該查詢實現類似於訊息消費的機制,首次查詢的時候會在記憶體中儲存一個歷史快照以及遊標(scroll_id),記錄當前訊息查詢的終止位置,下次查詢的時候將基於遊標進行消費(效能良好,維護成本高,在遊標失效前,不會更新資料,不夠靈活,一旦遊標建立size就不可改變,適用於大量資料匯出或者索引重建)
       (3) search_after: 效能優秀,類似於優化後的分頁查詢,歷史條件過濾掉資料。

      

四、注意事項

      1.使用search_after查詢,from引數設定為0或者-1.

      2.search_after is not a solution to jump freely to a random page but rather to scroll many queries in parallel. It is very similar to the scroll API but unlike it, the search_after parameter is stateless, it is always resolved against the latest version of the searcher. For this reason the sort order may change during a walk depending on the updates and deletes of your index. 意思就是說隨機地跳躍分頁,search_after的支援沒有scroll好。