【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
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條),效能大致是這樣:
分頁方式 | 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好。