數倉的等待檢視中,為什麼會有Hashjoin-nestloop

华为云开发者联盟發表於2024-02-28

本文分享自華為雲社群《GaussDB(DWS)等待檢視之Hashjoin-nestloop》,作者:Arrow0lf。

1. 業務場景

眾所周知,GaussDB(DWS)中有3種常見的join方式:HashJon/MergeJoin/NestLoop

但在有一些場景中,等待檢視中等待狀態會顯示為:HashJoin-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。

點選關注,第一時間瞭解華為雲新鮮技術~

相關文章