Hash Warning 事件類可用於監視在哈希操作過程中何時發生哈希遞歸或哈希終止(哈希釋放)。
當生成輸入無法裝入可用內存時,會發生哈希遞歸,這將導致輸入分割成單獨處理的多個分區。 如果這些分區中任何一個仍然大於可用內存,則該分區再拆分成子分區分別進行處理。 此拆分過程將一直持續到每個分區都小於可用內存,或達到最大遞歸級數(顯示在 IntegerData 數據列中)。
當哈希操作達到其最大遞歸級數並轉換到替換計劃以處理剩餘的分區數據時發生哈希釋放。 哈希釋放通常是由於傾斜數據造成的。哈希遞歸和哈希釋放會導致服務器的性能降低。
若要消除或降低哈希遞歸和哈希釋放的頻率,請執行下列操作之一:
確保正在聯接或分組的列上存在統計信息。
如果這些列上存在統計信息,請更新它們。
使用其他類型的聯接。 例如,使用 MERGE 或 LOOP 聯接(如果適合)。
增加計算機上的可用內存。 當沒有足夠的內存就地處理查詢,因此這些查詢需要溢出到磁盤時,會發生哈希遞歸或哈希釋放。
創建或更新聯接涉及的列上的統計信息是減少發生哈希遞歸或哈希釋放次數最有效的方法。
結合默認跟蹤,收集Hash Warning發生的次數:
DECLARE @Str NVARCHAR(MAX);
SELECT @Str = CONVERT(NVARCHAR(MAX), Value)
FROM :: FN_TRACE_GETINFO(DEFAULT) AS Tab
WHERE Tab.Property = 2
AND Traceid = 1;
SELECT COUNT(*) AS Cnt
FROM FN_TRACE_GETTABLE(@Str, DEFAULT) AS trace
INNER JOIN sys.trace_events te
ON te.trace_event_id = trace.EventClass
WHERE te.name LIKE 'Hash Warning'
AND trace.StartTime >= DATEADD(hh, -1, GETDATE());