interrogare i guadagni delle prestazioni rimuovendo il join interno dell'hash dell'operatore


9

Mentre provo ad applicare il contenuto di questa domanda alla mia situazione, sono un po 'confuso sul modo in cui potrei liberarmi dell'operatore Hash Match (Inner Join) se possibile.

Prestazioni delle query di SQL Server - eliminazione della necessità di Hash Match (Inner Join)

Ho notato il costo del 10% e mi chiedevo se potevo ridurlo. Vedi il piano di query di seguito.

inserisci qui la descrizione dell'immagine

Questo lavoro nasce da una domanda che ho dovuto sintonizzare oggi:

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 dopo aver aggiunto questi indici:

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

questa è la nuova query:

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

Ciò ha ridotto il tempo di esecuzione della query da 8 minuti a 1 secondo.

Tutti sono felici, ma vorrei comunque sapere se potevo fare di più, cioè rimuovendo in qualche modo l'operatore di hash match.

Perché è lì, in primo luogo, sto abbinando tutti i campi, perché hash?

Risposte:


14

i seguenti collegamenti forniranno una buona fonte di conoscenza riguardo ai piani di esecuzione.

Dalle basi del piano di esecuzione - Confusione hash match ho trovato:

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

"Il join hash è una delle operazioni di join più costose, in quanto richiede la creazione di una tabella hash per eseguire il join. Detto questo, è il join che è il migliore per input di grandi dimensioni, non ordinati. È il più dispendioso in termini di memoria di qualsiasi dei join

Il join hash legge prima uno degli input e esegue l'hashing della colonna join e inserisce i valori hash e colonna risultanti in una tabella hash creata in memoria. Quindi legge tutte le righe nel secondo input, esegue l'hashing e verifica le righe nel bucket hash risultante per le righe di join. "

che collega a questo post:

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

Puoi spiegare questo piano di esecuzione? fornisce buoni spunti sul piano di esecuzione con, non specifici per l'hash match ma rilevanti.

Le scansioni costanti sono un modo per SQL Server di creare un bucket in cui inserirà qualcosa in seguito nel piano di esecuzione. Ho pubblicato una spiegazione più approfondita qui . Per capire a cosa serve la scansione costante, è necessario approfondire il piano. In questo caso, sono gli operatori di calcolo scalare che vengono utilizzati per popolare lo spazio creato dalla scansione costante.

Gli operatori di calcolo scalare vengono caricati con NULL e il valore 1045876, quindi verranno chiaramente utilizzati con il loop join nel tentativo di filtrare i dati.

La parte davvero interessante è che questo piano è Trivial. Significa che ha attraversato un processo di ottimizzazione minimo. Tutte le operazioni stanno portando all'intervallo di unione. Questo è usato per creare un set minimo di operatori di confronto per una ricerca di indice ( dettagli su questo qui ).

In questa domanda: posso ottenere SSMS per mostrarmi i costi della query effettiva nel riquadro del piano di esecuzione? Sto risolvendo problemi di prestazioni su una procedura memorizzata multistatement in SQL Server. Voglio sapere su quali parti dovrei trascorrere del tempo.

Capisco da Come posso leggere il costo della query ed è sempre una percentuale? che anche quando viene detto a SSMS di includere il piano di esecuzione effettivo, le cifre "Costo query (relativo al batch)" sono ancora basate su stime dei costi, che possono essere molto lontane dagli effettivi

Misurazione delle prestazioni delle query: "Costo query piano di esecuzione" vs "Tempo impiegato" fornisce buone informazioni per quando è necessario confrontare le prestazioni di 2 query diverse.

In Lettura di un piano di esecuzione di SQL Server è possibile trovare ottimi suggerimenti per la lettura del piano di esecuzione.

Altre domande / risposte che mi sono piaciute molto perché sono rilevanti per questo argomento, e per mio riferimento personale vorrei citare sono:

Come ottimizzare la query T-SQL utilizzando il piano di esecuzione

sql può generare un buon piano per questa procedura?

I piani di esecuzione differiscono per la stessa istruzione SQL

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.