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());