本文分享自華為雲社群《GaussDB(DWS)等待檢視之Hashjoin-nestloop》,作者:Arrow0lf。
1. 業務場景
眾所周知,GaussDB(DWS)中有3種常見的join方式:HashJon/MergeJoin/NestLoop
但在有一些場景中,等待檢視中等待狀態會顯示為:HashJoin-nestloop,如下圖所示。這種表示什麼含義?
2. 基本原理
為了明白該狀態的原因,首先思考如下場景:當業務側兩張大表join時,如果由於未做analyze或統計資訊不準,導致build hash的一側選擇了大表,且該表在join列上重複值很多,會導致hashjoin時記憶體膨脹,當記憶體不足時,hashjon運算元會下盤,但是由於join列上存在大量重複值,下盤檔案無法有效分裂,此時,如果將整個檔案都讀取到記憶體中,會導致記憶體佔用很高,出現記憶體過載,導致其他業務記憶體不足報錯。
為了解決該場景,在向量化hashjoin時,當使用內表建立的hash表過大導致記憶體不足時,不再強制進行hashjoin,會透過內外表交換或執行nestloop使查詢平穩進行,防止出現記憶體報錯,此時,等待檢視狀態為“HashJoin-nestloop”
上述特性透過hashjoin_spill_strategy引數控制,預設為0,取值範圍為0-6的整數,詳情可以參考產品文件(8.1.2及以上版本),簡單來講:
取值為0或5,hashjoin時會先嚐試內外表交換,如果仍然記憶體佔用高,會選擇nestloop;
取值為1或6,hashjoin時會先嚐試內外標交換,如果仍然記憶體佔用高,會強行執行hashjoin;
取值為2,hashjoin行為和原本的行為保持一致,即使記憶體不夠,也會強制執行hashjoin
3. 業務影響
當等待檢視出現Hashjoin-nestloop時,可能會導致原來記憶體佔用高,單能執行成功的語句,在被轉換成nestloop後,可能會短時間執行不出來。尤其是當資料量變化較大,統計資訊差異較大時,容易出現執行計劃非最優場景下的效能劣化。
4. 解決方法
如果出現上述HashJoin-nestloop時間長,導致業務超時的情況。可以將引數hashjoin_spill_strategy設定為2進行規避。不再進行內外表交換或執行nestloop,使業務行為與之前的行為保持一致。
在記憶體充裕的場景下,可以全域性設定為2。
點選關注,第一時間瞭解華為雲新鮮技術~