Ao tentar aplicar o conteúdo desta pergunta abaixo à minha própria situação, estou um pouco confuso sobre como me livrar do operador Hash Match (Inner Join), se possível.
Desempenho de consulta do SQL Server - removendo a necessidade de Hash Match (Inner Join)
Percebi o custo de 10% e fiquei imaginando se poderia reduzi-lo. Veja o plano de consulta abaixo.
Este trabalho vem de uma consulta que eu tive que ajustar hoje:
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
e depois de adicionar estes índices:
---------------------------------------------------------------------
-- 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
esta é a nova consulta:
----------------------------------------------------------------------------
-- 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
Isso reduziu o tempo de execução da consulta de 8 minutos para 1 segundo.
Todo mundo está feliz, mas ainda assim gostaria de saber se poderia fazer mais, ou seja, removendo de alguma forma o operador de combinação de hash.
Por que está lá em primeiro lugar, estou combinando todos os campos, por que hash?
fonte