通过删除运算符哈希匹配内连接来提高查询性能

Mar*_*lli 9 performance index sql-server execution-plan sql-server-2014 query-performance

在尝试将下面这个问题的内容应用于我自己的情况时,如果可能的话,我对如何摆脱运算符 Hash Match (Inner Join) 感到有些困惑。

SQL Server 查询性能 - 消除对哈希匹配(内部联接)的需要

我注意到 10% 的成本,并想知道我是否可以减少它。请参阅下面的查询计划。

在此处输入图片说明

这项工作来自我今天必须调整的查询:

SELECT c.AccountCode, MIN(d.CustomerSID) 
FROM   Stage.Customer c 
INNER JOIN Dimensions.Customer d  ON c.Email = d.Email
                                  OR (
                                          c.HomePostCode = d.HomePostCode
                                       AND c.StrSurname = d.strSurname
                                                                    )
GROUP BY c.AccountCode
Run Code Online (Sandbox Code Playgroud)

添加这些索引后:

---------------------------------------------------------------------
-- Create the indexes
---------------------------------------------------------------------

CREATE NONCLUSTERED INDEX IDX_Stage_Customer_HOME_SURNAME_INCL
ON Stage.Customer(HomePostCode ,strSurname)
INCLUDE (AccountCode)
--WHERE HASEMAIL = 0
--WITH (ONLINE=ON, DROP_EXISTING = ON)
go


CREATE NONCLUSTERED INDEX IDX_Dimensions_Customer_HOME_SURNAME_INCL
ON Dimensions.Customer(HomePostCode ,strSurname)
INCLUDE (AccountCode,CustomerSID)
--WHERE HASEMAIL = 0
--WITH (ONLINE=ON, DROP_EXISTING = ON)
go



CREATE NONCLUSTERED INDEX IDX_Stage_Customer_EMAIL_INCL
ON Stage.Customer(EMAIL)
INCLUDE (AccountCode)
--WHERE HASEMAIL = 1
--WITH (ONLINE=ON, DROP_EXISTING = ON)
go


CREATE NONCLUSTERED INDEX IDX_Dimensions_Customer_EMAIL_INCL
ON Dimensions.Customer(EMAIL)
INCLUDE (AccountCode,CustomerSID)
--WHERE HASEMAIL = 1
--WITH (ONLINE=ON, DROP_EXISTING = ON)
go
Run Code Online (Sandbox Code Playgroud)

这是新查询:

----------------------------------------------------------------------------
-- new query 
----------------------------------------------------------------------------

SELECT * 
FROM (    
SELECT AccountCode
     ,RO=ROW_NUMBER () OVER (PARTITION BY AccountCode ORDER BY CustomerSID)
     --,CustomerSID=MIN(CustomerSID) OVER (PARTITION BY AccountCode ORDER BY AccountCode)
       ,CustomerSID
FROM (    
          SELECT c.AccountCode, D.CustomerSID
       FROM   Stage.Customer c 
       INNER JOIN Dimensions.Customer d  ON c.Email = d.Email

          UNION ALL

          SELECT c.AccountCode, D.CustomerSID
       FROM   Stage.Customer c 
       INNER JOIN Dimensions.Customer d  ON c.HomePostCode = d.HomePostCode
                                        AND c.StrSurname = d.strSurname
) RADHE
) R1
WHERE RO = 1
Run Code Online (Sandbox Code Playgroud)

这将查询执行时间从 8 分钟减少到 1 秒。

每个人都很高兴,但我仍然想知道我是否可以完成更多工作,即通过某种方式删除哈希匹配运算符。

为什么它首先存在,我匹配所有字段,为什么散列?

Mar*_*lli 14

以下链接将提供有关执行计划的良好知识来源。

Execution Plan Basics - Hash Match Confusion我发现:

来自 http://sqlinthewild.co.za/index.php/2007/12/30/execution-plan-operations-joins/

“散列连接是成本较高的连接操作之一,因为它需要创建一个散列表来进行连接。也就是说,它是最适合大型未排序输入的连接。它是所有连接中内存最密集的的连接

散列连接首先读取其中一个输入并对连接列进行散列,然后将生成的散列和列值放入内存中构建的散列表中。然后它读取第二个输入中的所有行,对它们进行散列,并检查结果散列桶中的行是否有连接行。”

这篇文章的链接:

http://blogs.msdn.com/b/craigfr/archive/2006/08/10/687630.aspx

你能解释一下这个执行计划吗?提供有关执行计划的良好见解,不是特定于哈希匹配而是相关的。

持续扫描是 SQL Server 创建一个存储桶的一种方式,它将在执行计划中稍后放置一些东西。我在这里发布了更详尽的解释。要了解持续扫描的目的,您必须进一步查看计划。在这种情况下,计算标量运算符用于填充由常量扫描创建的空间。

Compute Scalar 运算符加载了 NULL 和值 1045876,因此它们显然将与 Loop Join 一起使用以过滤数据。

真正酷的部分是这个计划是微不足道的。这意味着它经历了一个最小的优化过程。所有操作都导致合并间隔。这用于为索引查找创建一组最小的比较运算符(此处有详细说明)。

在这个问题中: 我可以让 SSMS 向我显示执行计划窗格中的实际查询成本吗? 我正在修复 SQL Server 中多语句存储过程的性能问题。我想知道我应该花时间在哪一部分上。

我从如何阅读查询成本中了解到,它总是一个百分比吗?即使当 SSMS 被告知包括实际执行计划时,“查询成本(相对于批次)”数字仍然基于成本估算,这可能与实际情况相差甚远

测量查询性能:“执行计划查询成本”与“所用时间” 在您需要比较 2 个不同查询的性能时提供了很好的信息。

阅读 SQL Server 执行计划中,您可以找到阅读执行计划的重要提示。

我非常喜欢的其他问题/答案,因为它们与这个主题相关,我想引用的个人参考是:

如何使用执行计划优化 T-SQL 查询

sql 可以为这个程序生成一个好的计划吗?

相同 SQL 语句的执行计划不同


归档时间:

查看次数:

49891 次

最近记录:

5 年,11 月 前