OVH Cloud OVH Cloud

Explications sur Stratégies de jointures

4 réponses
Avatar
Yann
Bonjour !

Est-ce que qqn pourrais m'expliquer avec des mots simples la différence
entre les stratégies de jointure de fusion, de hachage, et de boucles
imriquées ?

Merci d'avance à la personne qui voudra bien m'expliquer :-)

4 réponses

Avatar
BVesan
Bonjour,
Partons du code suivant
SELECT TABLE1.*
FROM TABLE1 INNER JOIN TABLE2 ON TABLE1.COL1 = TABLE2.COL1
WHERE TABLE2.COL2='TOTO'

Boucles imbriquées:
Cette méthode consiste à exécuter pour chaque rang de TABLE1 une recherche
sur TABLE2 en se basant sur les critères TABLE2.COL2='TOTO' et TABLE2.COL1=
<VALEUR DU RANG ACTUEL DE TABLE1.COL1>.
Intéressant donc lorsque TABLE1 est très petite, et vite consommateur
lorsque TABLE1 est grande.

Hachage:
Il s'agit de créer une table de hachage pour TABLE2, c-a-d un tableau à deux
entrées faisant correspondre le résultat d'une fonction appliquée sur COL1
(appelé clé de hachage) avec l'ensemble des rangs pour cette même valeur .
Ensuite,pour chaque rang de TABLE1, on utilise le résultat de cette même
fonction sur COL1 pour identifier les rangs correspondants de TABLE2.

Intéressant lorsqu'aucun indexe ne facilite la jointure et que TABLE1 et
TABLE2 sont de taille similaire

Fusion ordonnée (je ne sais pas si SQL Server gère un autre type de fusion):
Il s'agit d'abord d'ordonner les rangs des deux tables selon la valeur de
COL1.
La fusion correspond ensuite au rejet des premières lignes de TABLE1 dont la
valeur de TABLE1.COL1 est inférieure à la première valeur TABLE2.COL1, puis à
celui des lignes suivantes de TABLE2 dont la valeur de TABLE2.COL1 est
inférieure à la seconde valeur de TABLE1.COL1, et ainsi de suite.

Cette méthode est très intéressante lorsque les tables sont déjà ordonnnées
selon la colonne de jointure et que leur taille est similaire.
Avatar
Yann
Ok merci pour votre réponse,

Mais votre explication m'amenne à de nouvelles questions.
Au niveau des boucles imbriqués, que se passe t il si table1 est plus grande
que table2, l'optimiseur va t'il automatiquement choisir table2 comme table
de référence à comparer avec l'autre table plus grande (donc table1)

Pouvez vous me confirmer qu'au niveau du hachage, l'optimiseur va rassembler
(ou plutot faire correspondre) toutes les lignes ayant le même id (à supposer
que l'id est la collone utilisé pour la jointure) à un HASH généré, puis
après avoir rassemblé tous ces HASH dans un tableau, lire ce tableau en liant
chaque HASH généré à partir des ids de la table2 avec le hash de l'id de la
table1 (HASH qui devait être les même si l'id est le même de chaque coté)

Enfin pour la fusion, voulez vous dire par là que l'on est obligé de créer
des index ordonnés sur les collones de jointure (pour trier les infos) pour
que ca marche ?
Ou est ce que ca marche même si on n'a pas d'index ordonné, mais
l'optimiseur va devoir trier au moment de l'exécution les lignes pour simuler
un index ordonné, ce qui entrainera une baisse des perf par rapport à des
collones qui étaient déja triées ?

Encore merci pour votre réponse

"BVesan" a écrit :


Bonjour,
Partons du code suivant
SELECT TABLE1.*
FROM TABLE1 INNER JOIN TABLE2 ON TABLE1.COL1 = TABLE2.COL1
WHERE TABLE2.COL2='TOTO'

Boucles imbriquées:
Cette méthode consiste à exécuter pour chaque rang de TABLE1 une recherche
sur TABLE2 en se basant sur les critères TABLE2.COL2='TOTO' et TABLE2.COL1=
<VALEUR DU RANG ACTUEL DE TABLE1.COL1>.
Intéressant donc lorsque TABLE1 est très petite, et vite consommateur
lorsque TABLE1 est grande.

Hachage:
Il s'agit de créer une table de hachage pour TABLE2, c-a-d un tableau à deux
entrées faisant correspondre le résultat d'une fonction appliquée sur COL1
(appelé clé de hachage) avec l'ensemble des rangs pour cette même valeur .
Ensuite,pour chaque rang de TABLE1, on utilise le résultat de cette même
fonction sur COL1 pour identifier les rangs correspondants de TABLE2.

Intéressant lorsqu'aucun indexe ne facilite la jointure et que TABLE1 et
TABLE2 sont de taille similaire

Fusion ordonnée (je ne sais pas si SQL Server gère un autre type de fusion):
Il s'agit d'abord d'ordonner les rangs des deux tables selon la valeur de
COL1.
La fusion correspond ensuite au rejet des premières lignes de TABLE1 dont la
valeur de TABLE1.COL1 est inférieure à la première valeur TABLE2.COL1, puis à
celui des lignes suivantes de TABLE2 dont la valeur de TABLE2.COL1 est
inférieure à la seconde valeur de TABLE1.COL1, et ainsi de suite.

Cette méthode est très intéressante lorsque les tables sont déjà ordonnnées
selon la colonne de jointure et que leur taille est similaire.





Avatar
BVesan
> Au niveau des boucles imbriqués, que se passe t il si table1 est plus grande
que table2, l'optimiseur va t'il automatiquement choisir table2 comme table
de référence à comparer avec l'autre table plus grande (donc table1)



J'ai choisi de manière arbitraire l'ordre des tables pour l'exemple. Ce sont
les statistiques sur les colonnes et indexes des tables qui permettent à
l'Optimiser de choisir le type de jointure, et bien entendu de choisir
laquelle des tables sera considérée comme la "petite" .


Pouvez vous me confirmer qu'au niveau du hachage, l'optimiseur va rassembler
(ou plutot faire correspondre) toutes les lignes ayant le même id (à supposer
que l'id est la collone utilisé pour la jointure) à un HASH généré, puis
après avoir rassemblé tous ces HASH dans un tableau, lire ce tableau en liant
chaque HASH généré à partir des ids de la table2 avec le hash de l'id de la
table1 (HASH qui devait être les même si l'id est le même de chaque coté)



C'est bien ça. Et une fois le groupe de rangs de TABLE2 connu, un matching
sur chacun des rangs est effectué.

Enfin pour la fusion, voulez vous dire par là que l'on est obligé de créer
des index ordonnés sur les collones de jointure (pour trier les infos) pour
que ca marche ?
Ou est ce que ca marche même si on n'a pas d'index ordonné, mais
l'optimiseur va devoir trier au moment de l'exécution les lignes pour simuler
un index ordonné, ce qui entrainera une baisse des perf par rapport à des
collones qui étaient déja triées ?


Exactement. Si aucun indexe ne permet de disposer des données de manière
ordonnée, il y a bien une première phase de tri.

Encore une fois, c'est l'Optimiseur (à moins que le type de jointure ne soit
forcé) qui choisit le type à appliquer sur une jointure. En fonction donc des
volumétries relatives, de l'existence ou non de données ordonnées, de la
cardinalité des colonnes, ...
Avatar
Yann
Merci beaucoup !

"BVesan" a écrit :

> Au niveau des boucles imbriqués, que se passe t il si table1 est plus grande
> que table2, l'optimiseur va t'il automatiquement choisir table2 comme table
> de référence à comparer avec l'autre table plus grande (donc table1)

J'ai choisi de manière arbitraire l'ordre des tables pour l'exemple. Ce sont
les statistiques sur les colonnes et indexes des tables qui permettent à
l'Optimiser de choisir le type de jointure, et bien entendu de choisir
laquelle des tables sera considérée comme la "petite" .


> Pouvez vous me confirmer qu'au niveau du hachage, l'optimiseur va rassembler
> (ou plutot faire correspondre) toutes les lignes ayant le même id (à supposer
> que l'id est la collone utilisé pour la jointure) à un HASH généré, puis
> après avoir rassemblé tous ces HASH dans un tableau, lire ce tableau en liant
> chaque HASH généré à partir des ids de la table2 avec le hash de l'id de la
> table1 (HASH qui devait être les même si l'id est le même de chaque coté)

C'est bien ça. Et une fois le groupe de rangs de TABLE2 connu, un matching
sur chacun des rangs est effectué.

> Enfin pour la fusion, voulez vous dire par là que l'on est obligé de créer
> des index ordonnés sur les collones de jointure (pour trier les infos) pour
> que ca marche ?
> Ou est ce que ca marche même si on n'a pas d'index ordonné, mais
> l'optimiseur va devoir trier au moment de l'exécution les lignes pour simuler
> un index ordonné, ce qui entrainera une baisse des perf par rapport à des
> collones qui étaient déja triées ?
Exactement. Si aucun indexe ne permet de disposer des données de manière
ordonnée, il y a bien une première phase de tri.

Encore une fois, c'est l'Optimiseur (à moins que le type de jointure ne soit
forcé) qui choisit le type à appliquer sur une jointure. En fonction donc des
volumétries relatives, de l'existence ou non de données ordonnées, de la
cardinalité des colonnes, ...