阅读以下博客后,我明白hash match
聚合导致blocking
. 使用适当的索引可以将其制作为stream aggregate
.
我有一个数据库,其中包含多年前创建的 200 多个表。我正在尝试查找当前正在使用hash match
聚合运算符的 group by 的所有查询。我发现的一种可能性是像下面这样使用 dmv。但我不知道如何过滤它以仅列出带有hash match
聚合运算符的查询。如何做到这一点?此外,从大局来看,除了遵循 dmv 之外,还有哪些其他选项可以获取此信息?
SELECT cp.objtype AS ObjectType,
OBJECT_NAME(st.objectid,st.dbid) AS ObjectName,
cp.usecounts AS ExecutionCount,
st.TEXT AS QueryText,
qp.query_plan AS QueryPlan
FROM sys.dm_exec_cached_plans AS cp
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) AS qp
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS st
WHERE st.TEXT LIKE '%GROUP%'
不可能直接将部分查询文本(例如
GROUP BY
)与最终执行计划中的特定操作联系起来。您可以编写查询来查找符合以下条件的计划:
GROUP BY
子句...这不是一回事,因为这会找到使用流聚合实现分组逻辑的计划,替换为另一个操作,甚至完全删除 - 但由于某些其他原因恰好也包含哈希匹配聚合.
例如:
GROUP BY
如果它们之间的空格数量(或类型)与查询预期的不同,GROUP
这BY
可能会错过一些查询。也许用空格替换所有空格并将连续的空格折叠成一个空格可以在之前完成,LIKE
或者改用 SQLCLR 和正则表达式。您需要手动检查结果以确定哈希匹配聚合是否与
GROUP BY
子句直接相关。上面的查询可能会被扩展,以根据分组列检查计划HashKeysBuild元素,但由于优化器操作,这很难做到正确。