Principes de base du plan d'exécution - Confusion de correspondance de hachage

39

Je commence à apprendre les plans d'exécution et je ne comprends pas comment fonctionne exactement un match hash et pourquoi il serait utilisé dans une jointure simple:

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

entrez la description de l'image ici

Si je comprends bien, les résultats de l'analyse d'index supérieur deviennent la capacité de hachage et chaque ligne de l'analyse groupée d'index inférieure est recherchée. Je comprends très bien le fonctionnement des tables de hachage, mais je ne sais pas exactement quelles valeurs sont hachées dans un exemple comme celui-ci.

Qu'est-ce qui aurait du sens si le champ commun entre eux, l'identifiant, est haché - mais si c'est le cas, pourquoi hacher un nombre?

Kyle Brandt
la source

Réponses:

29

Comme le dit la réponse de SQLRockstar

idéal pour les grandes entrées non triées.

À présent,

  • À partir de l'analyse d'index Users.DisplayName (supposée non clusterisée), vous obtenez Users.Id (en supposant que le cluster est utilisé) = non trié.
  • Vous analysez également les messages pour OwnerUserId = non trié

Ceci est 2 entrées non ordonnées.

Je considérerais un index sur la table Posts sur OwnerUserId, y compris Title. Cela ajoutera un peu d’ordre d’un côté de l’entrée à JOIN +, il couvrira l’index

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

Vous constaterez peut-être que l'index Users.DisplayName ne sera pas utilisé et qu'il analysera le PK à la place.

gbn
la source
1
Ah d'accord, je vois maintenant, je pensais à Users.DisplayName a été commandé par le PK, ce qui n'est tout simplement pas le cas. Maintenant, l’utilisation de Hash me semble beaucoup plus logique. Merci!
Kyle Brandt
1
Vous pouvez également essayer l' OPTION (FAST n)indice, où n est le nombre approximatif de lignes que vous attendez. Cela va polariser l'optimiseur vers des boucles imbriquées plutôt que des jointures de hachage lorsque n est faible. La raison en est que les jointures de hachage sont rapides pour les jointures volumineuses mais que leur coût de démarrage est élevé. Les boucles imbriquées coûtent cher par ligne, mais peuvent être lancées à très bas coût. C'est donc une question de réglage fin basé sur vos données réelles et votre modèle d'accès.
Gaius
1
@ Gaius: Personnellement, je préférerais avoir des index que des allusions. Un indice n'est utile que pour la requête lorsque vous l'ajoutez. Aka l'indice devient un handicap avec le temps. Les index ont tendance à être utiles beaucoup plus longtemps.
gbn
1
ce n'est pas une proposition ni l'un ni l'autre :-)
Gaius
14

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

"La jointure par hachage est l’une des opérations les plus coûteuses, car elle nécessite la création d’une table de hachage. Cela dit, c’est la jointure qui convient le mieux aux entrées volumineuses non triées. C’est la plus gourmande en mémoire des jointures

La jointure de hachage lit d'abord l'une des entrées et hache la colonne de jointure et place le hachage résultant et les valeurs de la colonne dans une table de hachage construite en mémoire. Ensuite, il lit toutes les lignes de la deuxième entrée, les hache et les vérifie dans le compartiment de hachage résultant pour les lignes jointes. "

qui pointent vers ce post:

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

HTH

SQLRockstar
la source
Donc, si ce ne sont que les champs id, je suppose que je ne comprends pas l’avantage de hacher un champ id?
Kyle Brandt
+1 pour le lien vers le blog de Craig Freedman, il existe d'autres articles disponibles: blogs.msdn.com/b/craigfr/archive/tags/joins
Jeff
9

L'avantage de hacher un champ numérique est que vous prenez une valeur plus grande et que vous la divisez en morceaux plus petits afin qu'il puisse s'intégrer dans une table de hachage.

Voici comment Grant Fritchey le décrit:

"Une table de hachage, en revanche, est une structure de données qui divise tous les éléments en catégories de taille égale, ou compartiments, pour permettre un accès rapide aux éléments. La fonction de hachage détermine le compartiment dans lequel se trouve un élément. Par exemple, , vous pouvez prendre une ligne dans une table, la hacher en une valeur de hachage, puis stocker la valeur de hachage dans une table de hachage. "

Vous pouvez également obtenir une copie gratuite de son ebook "Dissection des plans d'exécution de SQL Server" à partir d'un lien de l'article suivant:

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

Jeff
la source
Une autre série d'articles intéressante sur JOINS
Jeff
Je suis en train de travailler à ma manière, mais en disséquant les plans d’exécution de SQL Server - c’est génial! Mais je suis un peu coincé sur ce point :-P
Kyle Brandt