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


9

在尝试将以下问题的内容应用于我自己的情况时,我有点困惑,因为如果可能的话,如何摆脱运算符哈希匹配(内部联接)。

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

在添加这些索引之后:

---------------------------------------------------------------------
-- 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

这是新的查询:

----------------------------------------------------------------------------
-- 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

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

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

为什么首先要匹配所有字段,为什么要哈希?

Answers:


14

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

执行计划基础-哈希匹配混乱中,我发现:

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加载Compute Scalar运算符,因此很显然,它们将与Loop Join一起使用,以尝试过滤数据。

真正很酷的部分是该计划是微不足道的。这意味着它经历了最少的优化过程。所有操作都将导致合并间隔。这用于为索引查找创建最小的比较运算符集(有关此内容的详细信息)。

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

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

衡量查询性能:“执行计划查询成本”与“花费时间” 为需要比较两个不同查询的性能提供了很好的信息。

在“ 读取SQL Server执行计划”中,您可以找到有关阅读执行计划的重要技巧。

我真正喜欢的其他问题/答案,因为它们与该主题相关,并且我个人希望引用的内容包括:

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.