Nozioni di base sul piano di esecuzione - Confusione della corrispondenza hash


39

Sto iniziando a imparare i piani di esecuzione e sono confuso su come funziona esattamente una partita di hash e perché sarebbe utilizzata in un semplice join:

select Posts.Title, Users.DisplayName
From Posts JOIN Users on
Posts.OwnerUserId = Users.Id
OPTION (MAXDOP 1)

inserisci qui la descrizione dell'immagine

A quanto ho capito, i risultati della scansione dell'indice principale diventano l'hash in grado e ogni riga nella scansione cluster dell'indice inferiore viene cercata. Capisco come le tabelle di hash funzionano almeno in una certa misura, ma sono confuso su quali valori vengono esattamente sottoposti a hash in un esempio come questo.

Cosa avrebbe senso per me è il campo comune tra loro, l'id, è cancellato - ma se è così, perché è un numero?

Risposte:


29

Come cita la risposta di SQLRockstar

ideale per input grandi e non ordinati.

Adesso,

  • dalla scansione dell'indice Users.DisplayName (assunto non cluster) si ottiene Users.Id (assumendo cluster) = non ordinato
  • Stai anche eseguendo la scansione dei messaggi per OwnerUserId = unsorted

Si tratta di 2 ingressi non ordinati.

Considererei un indice nella tabella Posts su OwnerUserId, incluso Title. Ciò aggiungerà un certo ordine su un lato dell'input a JOIN + coprirà l'indice

CREATE INDEX IX_OwnerUserId ON Posts (OwnerUserId) INCLUDE (Title)

È quindi possibile scoprire che l'indice Users.DisplayName non verrà utilizzato e verrà invece scansionato il PK.


1
Ah va bene, vedo ora, stavo pensando agli Utenti. Il Nome Display è stato ordinato dal PK, il che non è il caso. Ora l'uso di Hash ha molto più senso per me. Grazie!
Kyle Brandt,

1
Puoi anche provare il OPTION (FAST n)suggerimento, dove n è il numero approssimativo di righe che ti aspetti. Ciò che farà è orientare l'ottimizzatore verso i loop nidificati anziché i join hash quando n è basso. Il motivo è che i join hash sono veloci per i join di grandi dimensioni ma hanno un costo di avvio elevato. I loop nidificati sono costosi per riga, ma possono iniziare in modo molto economico. Quindi è una questione di messa a punto in base ai dati effettivi e al modello di accesso.
Gaius,

1
@Gaius: Personalmente preferirei avere indici piuttosto che suggerimenti. Un suggerimento è utile solo per la query quando la aggiungi. Anche il suggerimento diventa una responsabilità nel tempo. Gli indici tendono ad essere utili molto più a lungo.
gbn

1
non è né una né una proposta :-)
Gaius,

14

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

HTH


Quindi se sono solo i campi ID, suppongo di non capire il vantaggio di eseguire l'hashing di un campo ID?
Kyle Brandt,

+1 per il link al blog di Craig Freedman, ci sono altri articoli di join disponibili: blogs.msdn.com/b/craigfr/archive/tags/joins
Jeff

9

Il vantaggio dell'hashing di un campo numerico è che stai prendendo un valore più grande e lo scomponi in pezzi più piccoli in modo che possa adattarsi a una tabella di hash.

Ecco come lo descrive Grant Fritchey:

"Una tabella di hash, d'altra parte, è una struttura di dati che divide tutti gli elementi in categorie di dimensioni uguali, o bucket, per consentire un rapido accesso agli elementi. La funzione di hashing determina in quale bucket si trova un elemento. Ad esempio , puoi prendere una riga da una tabella, hash in un valore hash, quindi memorizzare il valore hash in una tabella hash. "

È inoltre possibile ottenere una copia gratuita del suo ebook "Analisi dei piani di esecuzione di SQL Server" da un collegamento dal seguente articolo:

Fonte: http://www.simple-talk.com/sql/performance/graphical-execution-plans-for-simple-sql-queries/


Un'altra interessante serie di articoli su JOINS
Jeff

Sto lavorando a modo mio sezionando i piani di esecuzione di SQL Server - è fantastico! Ma sono rimasto un po 'bloccato su questo punto :-P
Kyle Brandt,

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.