ES分頁查詢速度慢調優
阿新 • • 發佈:2022-05-23
es分頁查詢
方式一:from + size
from + size方式查詢
from表示頁碼
size表示頁面大小
比如from為30,size為100,則要查詢第30頁,展示100條資料
那麼es查詢的方式為獲取到查詢條件(略)下的30 * 100等於3000條資料,然後給你返回最後的100條資料,前面的2900條資料將被過濾掉
而且es是有多個分片的話,將從每個分片去取得相應條件下的資料,然後彙總為3000條,最後返回其中的100條,所以分頁越深,ES處理的開銷就越大,佔用記憶體就越大。
優點
方式簡單,容易上手,針對資料量小的淺分頁,速度可以滿足要求
缺點
深分頁時查詢速度慢,對伺服器記憶體開銷大
方式二:scroll方案
通過scroll方式可以一次性查詢大量的資料,甚至全量資料,我們的第一次查詢(會返回一個scroll_id,使用此scroll_id來查詢下一組size大小的資料),會生成一個當前查詢條件的快照,後面的每次(翻頁)滾屏都是基於這個快照的結果,即使有新的資料進來,也不會影響這個快照的結果. 第一次查詢如下: POST /kibana_sample_data_ecommerce/_search?scroll=1m { "size": 10, "query": { "match_all" : { } } } scroll=1m表示很多人對scroll這個引數容易混淆,誤認為是查詢的限制時間。這個理解是錯誤的。這個時間其實指的是es把本次快照的結果快取起來的有效時間。 scroll 引數相當於告訴了ES我們的search context要保持多久,後面每個 scroll 請求都會設定一個新的過期時間,以確保我們可以一直進行下一頁操作。 通過scroll_id去拿資料的時候,可以不用設定index(索引名)跟size(資料大小)資訊,類似如下: POST /_search/scroll { "scroll" : "1m", "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAA5AWNGpKbFNMZnVSc3loXzQwb0tJZHBtZw==" } 以此類推,後面每次滾屏都把前一個的scroll_id複製過來
為什麼scroll比較塊
ES的檢索分為query(查詢)和fetch(獲取)階段,query階段的效率比較高,只是將滿足條件的文件id彙總起來,fetch階段基於每個分片的結果在coordinating(座標)節點上進行全域性排序,然後最終計算出結果。
scroll查詢的時候,在query階段把符合條件的文件id儲存在 search context(搜尋上下文)中,後面每次scroll分批取出只是根據scroll_id定位到遊標的位置,然後抓取size大小的結果集即可。
優點
適合實時性要求不高,要查詢大量資料的場景,適合報表匯出等業務或者ES內部的重置索引
缺點
實時性不高,只是往下一頁迭代查詢,不能往回查詢且不能獲取跳頁查詢
方式三:search after方案
search after使用實時遊標來幫我們解決實時滾動的問題,簡單來說前一次查詢的結果會返回一個唯一的字串,下次查詢再帶上這個字串
第一次查詢:
GET /kibana_sample_data_ecommerce/_search
{
"size" : 2,
"query": {
"bool": {
"must": [
{"match": {
"customer_first_name": "Diane"
}}
],
"filter": {
"range": {
"order_date": {
"gte": "2020-01-03"
}
}
}
}
},
"sort": [
{
"order_date": "desc",
"_id": "asc"
}
]
}
資料返回結果的最後一條裡面能獲取到order_date與_id
於是我們將使用search after
GET /kibana_sample_data_ecommerce/_search
{
"size" : 2,
"query": {
"bool": {
"must": [
{"match": {
"customer_first_name": "Diane"
}}
],
"filter": {
"range": {
"order_date": {
"gte": "2020-01-03"
}
}
}
}
},
"search_after":
[
1580597280000,
"RZz1f28BdseAsPClqbyw"
],
"sort": [
{
"order_date": "desc",
"_id": "asc"
}
]
}
"search_after":[1580597280000,"RZz1f28BdseAsPClqbyw"] 說明: search_after數組裡面是多個排序引數,用逗號隔開
當使用search_after引數時,from的值必須被設為0或者-1
實現原理
因為我們search_after傳遞了排序的唯一標識,ES只需從每個分片上拿到滿足條件的文件數量就行了,然後基於這些文件最終聚合成10條結果返回
優點
基於ES內部排序好的遊標,可以實時高效的進行分頁查詢
缺點
只能做下一頁這樣的查詢場景,不能隨機的指定頁數查詢(跳頁)。