瞭解雜湊聯結

雜湊聯結有兩個輸入:建置輸入與探查輸入。查詢最佳化工具會指派這些角色,使兩個輸入中比較小的一個做為建置輸入。

雜湊聯結用於許多種集合比對作業:內部聯結;左方、右方與完整外部聯結;左方、右方半聯結;交集;聯合;與差異。不僅如此,雜湊聯結的變數還可以執行重複移除和進行群組,例如 SUM(salary) GROUP BY department。這些修改方式只使用一個輸入,兼做組建與探查角色。

下列章節描述不同類型的雜湊聯結:In-Memory 雜湊聯結、寬限雜湊聯結和遞迴雜湊聯結。

In-Memory 雜湊聯結

雜湊聯結會先掃描或計算整個建置輸入,然後在記憶體中建立雜湊表。根據以雜湊鍵計算所得的雜湊值,將每一列插入雜湊桶中。如果整個建置輸入小於可用記憶體,就可以將所有資料列都插入雜湊表。這個組建階段後跟著探查階段。這時候會以逐列方式掃描或計算整個探查輸入,針對每個探查列計算雜湊鍵值、掃描對應的雜湊桶,並產生符合項目。

寬限雜湊聯結

如果記憶體放不下建置輸入,就會以幾個步驟進行雜湊聯結。這就是所謂的寬限雜湊聯結。每個步驟分別有組建階段與探查階段。最開始,會消耗整個組建與探查輸入,並分割 (對雜湊鍵使用雜湊函數) 成多個檔案。對雜湊鍵使用雜湊函數會保證任何兩個聯結資料錄一定在同一對檔案中。因此,本來是聯結兩個大型輸入的工作,變成是做好幾個相同的工作,但每個工作都變得比較小。然後再對每對分割檔案套用雜湊聯結。

遞迴雜湊聯結

如果建置輸入太大,使得標準外部聯結排序的輸入需要多個合併層級,就需要多個分割步驟與多個分割層級。如果只有一些分割很大,就僅對這部分使用額外的分割步驟。為了使所有分割步驟都盡可能達到最快的速度,所以使用大型的非同步 I/O 作業,使單一執行緒可以讓多部磁碟機保持忙碌。

[!附註]

如果建置輸入只比可用記憶體稍微大一點,就會將 In-memory 雜湊聯結和寬限雜湊聯結的元素合併到單一步驟中,而產生混合型雜湊聯結。

在最佳化期間不一定能夠判斷要使用哪一個雜湊聯結。因此,SQL Server 開始時會先使用 In-Memory 雜湊聯結,然後再依據建置輸入的大小,逐漸轉換成寬限雜湊聯結和遞迴雜湊聯結。

如果最佳化工具誤判哪個輸入較小,而選錯建置輸入,則建置和探查角色會動態地顛倒。雜湊聯結會確定使用溢位較小的檔案做為建置輸入。這個技術稱為「角色反轉」。當至少有一個雜湊聯結蔓延至磁碟之後,角色反轉就會發生於雜湊聯結內。

[!附註]

角色反轉的發生與任何查詢提示或結構無關。角色反轉不會顯示在查詢計畫中;當它發生時,使用者會看到。

Hash Bailout

Hash Bailout 一詞有時候是用來描述寬限雜湊聯結或遞迴雜湊聯結。

[!附註]

遞迴雜湊聯結或 Hash Bailout 會導致伺服器的效能降低。如果您在追蹤內看到許多 Hash Warning 事件,請在聯結的資料行上更新統計資料。

如需 Hash Bailout 的詳細資訊,請參閱<Hash Warning 事件類別>。