2010-01-21 7 views
6

J'ai exécuté une requête et inclus le plan d'exécution réel. Il y a un match de hachage qui m'intéresse parce que son sous-arbre utilise un index index au lieu d'une recherche d'index. Quand je souris sur ce match de hachage il y a une section appelée "sonde résiduelle". J'avais supposé que ce sont les valeurs auxquelles je m'associe. Ai-je raison ici ou y a-t-il une meilleure explication de ce que cela signifie?Question sur la façon de lire un plan d'exécution SQL

La deuxième question que j'ai eu concerne les index qu'il utilise. Dans mon exemple, je suis assez sûr que cette jointure se joint à deux colonnes. L'index qu'il s'agit d'analyser contient ces deux colonnes ainsi qu'une autre colonne qui n'est pas utilisée dans la jointure. J'avais l'impression que cela entraînerait une recherche d'index plutôt qu'une analyse. Est-ce que je me trompe?

Répondre

4

Un joint de hachage utilisera généralement (toujours?) Une analyse ou au moins une analyse de distance. Une jointure de hachage fonctionne en analysant les tables de jointure gauche et droite (ou une plage dans les tables) et en créant une table de hachage en mémoire qui contient toutes les valeurs 'vues' par les scans. Qu'est-ce qui est arrivé dans votre cas est la suivante: la QO a remarqué qu'elle peut obtenir toutes les valeurs d'une colonne C à partir d'un index non-cluster qui contient cette colonne (en tant que clé ou colonne incluse). Étant donné qu'un index non clusterisé est probablement assez étroit, la quantité totale d'E/S à analyser l'ensemble de l'index non clusterisé n'est pas exagérée. La QO a également considéré que le système avait suffisamment de RAM pour stocker une table de hachage en mémoire. En comparant le coût de cette requête (une analyse d'un index non clusterisé de bout en bout pour, disons, 10000 pages) avec le coût d'une boucle imbriquée utilisée pour rechercher (par exemple 5000 sondes à 2-3 pages chacune), le scan a gagné comme nécessitant moins d'IO. Bien sûr, c'est en grande partie de la spéculation de ma part, mais j'essaie de présenter l'affaire du point de vue de la QO, et le plan est probablement optimal.

Les facteurs qui ont contribué à ce choix de plan particulier seraient:

  • un grand nombre de candidats estimés sur le côté droit de la rejoindre
  • disponibilité de la colonne de jointure dans un indice restreint non cluster pour le côté gauche
  • de beaucoup de RAM

Pour une grande estimation du nombre de candidats, un meilleur choix que la jointure de hachage est que la fusion jointure, et que il faut que l'entrée soit pré-triée. Si le côté gauche peut offrir un chemin d'accès qui garantit un ordre sur la colonne jointe et que le côté droit a une possibilité similaire, vous pouvez vous retrouver avec la jointure de fusion, qui est la jointure la plus rapide.

+3

Un match de hachage n'utilise pas nécessairement un balayage. Il peut facilement impliquer une recherche dans des enregistrements particuliers, puis utiliser les résultats de cette recherche dans le match de hachage. Pour une boucle imbriquée, il gère un enregistrement à la fois, donc il est plus susceptible de préférer une recherche, mais cela ne signifie pas qu'un hachage préfère une analyse - il doit juste obtenir toutes les lignes qui correspondent potentiellement. Si vous filtrez les deux tables impliquées et que vous avez un index de couverture mais aussi un calcul, vous pouvez reproduire ce comportement. –

+0

@Rob: Je ne suis pas vendu là-dessus. Il m'a fallu un moment pour trouver une référence publique disponible, mais lisez http://blogs.msdn.com/craigfr/archive/2006/08/10/687630.aspx sur le fonctionnement de Hash-Join, à la fois la construction et la sonde phase * lire l'ensemble de l'entrée en un seul passage * ce genre de règles cherche. De plus, le pseudo-algorithme indique clairement qu'il n'y a pas de corrélation entre le côté gauche et le côté droit qui détermine le filtrage de la sonde. –

+0

Bien ... considérons d'abord l'installation. Créez deux tables, avec deux champs chacun. Index un sur le champ de filtre, y compris la colonne joinfield. Ensuite, nous allons les peupler de chiffres. créer une table dbo.table1 (id int identité (1,1) clé primaire , joinfield int , filterfield int ); aller créer table dbo.table2 (id int identité (1,1) clé primaire , joinfield int , filterfield int ); aller créer l'index ix1 sur dbo.table1 (champ de filtrage) include (joinfield); create index ix2 sur dbo.table2 (champ de filtrage) include (joinfield); aller –

4

This blog post will probably answer your first question.

Quant à votre deuxième, le balayage d'index peut être sélectionné par l'optimiseur dans un certain nombre de situations. Du haut de ma tête:

  • Si l'indice est très faible
  • Si la plupart des lignes de l'index seront sélectionnés par la requête

  • Si vous utilisez des fonctions dans le où clause de votre requête

Pour les deux premiers cas, il est plus efficace de faire un scan, donc l'optimiseur le choisit au cours d'une recherche. Pour le troisième cas, l'optimiseur n'a pas le choix.

+0

Très bon article, merci de l'avoir posté. Donc, est-ce qu'il dit que si la première colonne indexée n'est pas jointe par ma requête, cela pourrait entraîner un balayage d'index plutôt qu'une recherche? –

+1

Oui. Btw, son blog est vraiment bon pour en apprendre davantage sur le fonctionnement interne du serveur SQL. – womp

+0

Oui, j'ai été impressionné par ce que j'ai lu là-bas. L'ajoutant à ma liste. Merci de me pointer vers lui! –

2

1/Une correspondance de hachage signifie qu'elle prend un hachage de colonnes utilisées dans une jointure d'égalité, mais doit inclure toutes les autres colonnes impliquées dans la jointure (pour>, etc.) afin qu'elles puissent également être vérifiées. C'est là que les colonnes résiduelles entrent.

2/Une recherche d'index peut être faite si elle peut aller directement aux lignes que vous voulez. Peut-être appliquez-vous un calcul aux colonnes et utilisez-vous cela? Ensuite, il utilisera l'index comme une version plus petite des données, mais devra toujours vérifier chaque ligne (en appliquant le calcul sur chacun d'eux).