查找哈希匹配聚合

LCJ*_*LCJ 3 performance sql-server aggregate execution-plan performance-tuning

阅读以下博客后,我明白hash match聚合原因blocking。使用适当的索引,它可以作为stream aggregate.

  1. 阻塞/非阻塞聚合运算符
  2. 聚合的阻塞性质 - Rob Farley
  3. 哈希聚合-Craig Freedman

我有一个数据库,其中包含 200 多个多年前创建的表。我正在尝试通过 group by 查找当前正在使用hash match聚合运算符的所有查询。我发现的一种可能性是使用 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%'
Run Code Online (Sandbox Code Playgroud)

Pau*_*ite 8

不可能将查询文本的一部分(例如)与最终执行计划中的特定操作直接连接起来GROUP BY

可以编写查询来查找以下计划:

  • 包含哈希匹配聚合;和
  • 查询文本包含一个GROUP BY子句

...这不是完全相同的事情,因为这将找到分组逻辑是使用流聚合实现的计划,用另一个操作替换,甚至完全删除 - 但由于某些其他原因碰巧也包含哈希匹配聚合.

例如:

WITH XMLNAMESPACES
(
    DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan'
)
SELECT
    DECP.cacheobjtype,
    DECP.objtype,
    DECP.plan_handle,
    DEQP.objectid,
    DEQP.query_plan,
    DEST.[text]
FROM sys.dm_exec_cached_plans AS DECP
CROSS APPLY sys.dm_exec_query_plan(DECP.plan_handle) AS DEQP
CROSS APPLY sys.dm_exec_sql_text(DECP.plan_handle) AS DEST
WHERE
    1 = DEQP.query_plan.exist(
        '//RelOp[
            @PhysicalOp = "Hash Match"
            and @LogicalOp = ("Aggregate","Partial Aggregate","Flow Distinct")]')
    AND DEST.[text] LIKE N'%GROUP BY%';
Run Code Online (Sandbox Code Playgroud)

这可能会错过一些GROUP BY,如果他们有之间的空白不同数量(或类型)的查询GROUPBY比对查询的预期。也许可以在LIKEor 使用 SQLCLR 和正则表达式之前用空格替换所有空格并将连续的空格折叠成一个空格。

您需要手动检查结果以确定哈希匹配聚合是否与GROUP BY子句直接相关。上面的查询可能可以扩展,以根据分组列检查计划HashKeysBuild元素,但由于优化器操作,这很难做到正确。