Verbesserungen der Abfrageleistung durch Entfernen des inneren Joins für Operator-Hash-Übereinstimmungen

9

Während ich versuche, den Inhalt dieser Frage auf meine eigene Situation anzuwenden, bin ich etwas verwirrt darüber, wie ich den Operator Hash Match (Inner Join), wenn möglich, loswerden könnte.

SQL Server-Abfrageleistung - keine Hash-Übereinstimmung mehr erforderlich (Inner Join)

Ich bemerkte die Kosten von 10% und fragte mich, ob ich sie reduzieren könnte. Siehe den Abfrageplan unten.

Geben Sie hier die Bildbeschreibung ein

Diese Arbeit stammt aus einer Abfrage, die ich heute einstellen musste:

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

und nach dem Hinzufügen dieser Indizes:

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

Dies ist die neue Abfrage:

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

Dies hat die Ausführungszeit der Abfrage von 8 Minuten auf 1 Sekunde reduziert.

Alle sind glücklich, aber ich würde trotzdem gerne wissen, ob ich mehr erreichen könnte, dh indem ich den Hash-Match-Operator irgendwie entferne.

Warum ist es überhaupt da, ich stimme mit allen Feldern überein, warum Hash?

Marcello Miorelli
quelle

Antworten:

14

Die folgenden Links bieten eine gute Wissensquelle zu Ausführungsplänen.

Aus den Grundlagen des Ausführungsplans - Hash Match Confusion habe ich gefunden:

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

"Der Hash-Join ist eine der teureren Join-Operationen, da für den Join eine Hash-Tabelle erstellt werden muss. Dies ist jedoch der Join, der für große, unsortierte Eingaben am besten geeignet ist. Er ist der speicherintensivste von allen der Joins

Der Hash-Join liest zuerst eine der Eingaben und hasht die Join-Spalte und fügt den resultierenden Hash und die Spaltenwerte in eine im Speicher aufgebaute Hash-Tabelle ein. Dann liest es alle Zeilen in der zweiten Eingabe, hasht diese und überprüft die Zeilen im resultierenden Hash-Bucket auf die verbindenden Zeilen. "

welche Links zu diesem Beitrag:

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

Können Sie diesen Ausführungsplan erklären? bietet gute Einblicke in den Ausführungsplan mit, nicht spezifisch für die Hash-Übereinstimmung, aber relevant.

Die ständigen Scans sind eine Möglichkeit für SQL Server, einen Bucket zu erstellen, in den später im Ausführungsplan etwas eingefügt wird. Ich habe hier eine ausführlichere Erklärung veröffentlicht . Um zu verstehen, wofür der konstante Scan gedacht ist, müssen Sie den Plan genauer untersuchen. In diesem Fall werden die Operatoren "Skalar berechnen" verwendet, um den durch den konstanten Scan erstellten Speicherplatz zu füllen.

Die Compute Scalar-Operatoren werden mit NULL und dem Wert 1045876 geladen, sodass sie eindeutig mit dem Loop Join verwendet werden, um die Daten zu filtern.

Der wirklich coole Teil ist, dass dieser Plan Trivial ist. Dies bedeutet, dass ein minimaler Optimierungsprozess durchlaufen wurde. Alle Vorgänge führen zum Zusammenführungsintervall. Dies wird verwendet, um einen minimalen Satz von Vergleichsoperatoren für eine Indexsuche zu erstellen ( Details dazu hier ).

In dieser Frage: Kann ich SSMS veranlassen, mir die tatsächlichen Abfragekosten im Bereich Ausführungsplan anzuzeigen? Ich behebe Leistungsprobleme bei einer in SQL Server gespeicherten Prozedur mit mehreren Anweisungen. Ich möchte wissen, für welche Teile ich Zeit verbringen soll.

Ich verstehe aus Wie lese ich Abfragekosten und ist es immer ein Prozentsatz? Selbst wenn SSMS angewiesen wird, den tatsächlichen Ausführungsplan aufzunehmen, basieren die Zahlen für "Abfragekosten (relativ zum Stapel)" immer noch auf Kostenschätzungen, die weit von den tatsächlichen Werten entfernt sein können

Messen der Abfrageleistung: "Abfragekosten für Ausführungsplan" im Vergleich zu "Zeitaufwand" bietet gute Informationen darüber, wann Sie die Leistung von zwei verschiedenen Abfragen vergleichen müssen.

Unter Lesen eines SQL Server-Ausführungsplans finden Sie nützliche Tipps zum Lesen des Ausführungsplans.

Andere Fragen / Antworten, die mir sehr gut gefallen haben, weil sie für dieses Thema relevant sind, und für meine persönliche Referenz möchte ich zitieren:

So optimieren Sie die T-SQL-Abfrage mithilfe des Ausführungsplans

Kann SQL einen guten Plan für dieses Verfahren erstellen?

Ausführungspläne unterscheiden sich für dieselbe SQL-Anweisung

Marcello Miorelli
quelle