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.
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. –
@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. –
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 –