實踐應用發現,以下情況都會比較慢:
1)待聚合文檔數比較多(千萬、億、十億甚至更多);
2)聚合條件比較複雜(多重條件聚合);
3)全量聚合(翻頁的場景用)。
2、聚合優化方案探讨
優化方案一:預設深度優先聚合改為廣度優先聚合。
"collect_mode" : "breadth_first"
1
depth_first 直接進行子聚合的計算
breadth_first 先計算出目前聚合的結果,針對這個結果在對子聚合進行計算。
優化方案二: 每一層terms aggregation内部加一個 “execution_hint”: “map”。
"execution_hint": "map"
國内解釋最詳細的版本來自Wood大叔:
————————————————
版權聲明:本文為CSDN部落客「銘毅天下」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。
原文連結:
https://blog.csdn.net/laoyang360/article/details/79253294Map方式的結論可簡要概括如下:
1)查詢結果直接放入記憶體中建構map,在查詢結果集小的場景下,速度極快;
2)但如果待結果集合很大的情況,map方式不一定也快。
3、做個實驗
聚合的平衡點是多少呢?
3.1 實驗場景
場景一:在近億的document中,檢索滿足給定條件的資料,并對聚合結果全量聚合。
場景二:在百萬級别的document中,全量聚合。
場景三:在近億級别的document中,全量聚合。
3.2 聚合操作
POST index_*/_search
{
"sort": [
{
"nrply": "desc"
}
],
"aggs": {
"count_ix": {
"terms": {
"field": "ix_id",
"execution_hint": "map",
"size": 1000,
"collect_mode": "breadth_first"
},
"size":0
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1)修改索引名稱,以擷取更多的文檔。
2)map模式添加 “execution_hint”: “map”,預設是global_ordinals模式。
3)”size”: 1000,設定聚合取值。
3.3 聚合結果
3.4 結果分析
對比場景一與場景二、三,說明:
1)當結果集合比較少的時候,map聚合方式明顯速度更快,速度提升了接近5倍!
2)當結果集合比較大的時候(百萬——億級别)的時候,傳統的聚合方式會比map方式快。
4、小結
1)global_ordinals是關鍵字字段( keyword field )的預設選項,它使用 全局順序(global ordinals) 來動态配置設定存儲區,是以記憶體使用情況與作為聚合作用域一部分的文檔值的數量成線性關系。
2)隻有極少數文檔與查詢比對比對時才應考慮使用map方式。
預設情況下,隻有在腳本上運作聚合時才會使用map,因為它們沒有序号( ordinals )。
否則,基于 順序(ordinals) 的執行模式會相對更快。
參考:
http://t.cn/R8WI6QD http://t.cn/R8WIKta https://elasticsearch.cn/question/1008 http://t.cn/R8WIpYn