web-dev-qa-db-fra.com

SQL JOIN vs performance IN?

J'ai un cas où utiliser un JOIN ou un IN me donnera les bons résultats ... Ce qui a typiquement de meilleures performances et pourquoi? À quel point cela dépend-il du serveur de base de données que vous utilisez? (FYI j'utilise MSSQL)

150
Polaris878

De manière générale, IN et JOIN sont des requêtes différentes pouvant donner des résultats différents.

SELECT  a.*
FROM    a
JOIN    b
ON      a.col = b.col

n'est pas la même chose que

SELECT  a.*
FROM    a
WHERE   col IN
        (
        SELECT  col
        FROM    b
        )

, sauf si b.col est unique.

Cependant, ceci est le synonyme de la première requête:

SELECT  a.*
FROM    a
JOIN    (
        SELECT  DISTINCT col
        FROM    b
        )
ON      b.col = a.col

Si la colonne jointe est UNIQUE et marquée comme telle, ces deux requêtes donnent le même plan dans SQL Server.

Si ce n'est pas le cas, alors IN est plus rapide que JOIN sur DISTINCT.

Voir cet article sur mon blog pour plus de détails sur les performances:

181
Quassnoi

C'est marrant que tu mentionnes ça, j'ai fait un blog sur ce sujet même.

Voir Oracle vs MySQL vs SQL Server: agrégation vs jointures

Réponse courte: vous devez le tester et les bases de données individuelles varient beaucoup.

26
cletus

C'est assez difficile à dire - pour vraiment savoir lequel fonctionne le mieux, il vous faut en fait profiler les temps d'exécution.

En règle générale, je pense que si vous avez des index sur vos colonnes de clé étrangère et que vous utilisez uniquement (ou principalement) les conditions INNER JOIN, alors JOIN sera légèrement plus rapide.

Mais dès que vous commencez à utiliser OUTER JOIN ou si vous manquez d'index de clé étrangère, le IN peut être plus rapide.

Marc

4
marc_s

Un article intéressant sur les différences logiques: SQL Server: JOIN vs IN vs EXISTS - la différence logique

Je suis à peu près sûr que, en supposant que les relations et les index soient maintenus, une jointure fonctionnera globalement mieux (plus d'efforts sont nécessaires pour travailler avec cette opération plutôt qu'avec d'autres). Si vous y réfléchissez de manière conceptuelle, c’est la différence entre 2 requêtes et 1 requête.

Vous devez le connecter à l'analyseur de requêtes et l'essayer pour voir la différence. Examinez également le plan d'exécution de la requête et essayez de minimiser les étapes.

4
AdamSane

Ce fil est assez vieux mais toujours mentionné souvent. À mon goût personnel, il est un peu incomplet, car il existe un autre moyen de demander à la base de données avec le mot-clé EXISTS que j'ai trouvé plus rapide plus souvent.

Donc, si vous ne vous intéressez qu'aux valeurs de la table a, vous pouvez utiliser cette requête:

SELECT  a.*
FROM    a
WHERE   EXISTS (
    SELECT  *
    FROM    b
    WHERE   b.col = a.col
    )

La différence pourrait être énorme si col n'est pas indexé, car la base de données n'a pas à rechercher tous les enregistrements de b qui ont la même valeur dans col, il suffit de trouver le tout premier. S'il n'y a pas d'index sur b.col et que beaucoup d'enregistrements dans b, une analyse de table pourrait en être la conséquence. Avec IN ou JOIN, il s'agira d'une analyse complète de la table. Avec EXISTS, il s'agira uniquement d'une analyse partielle de la table (jusqu'à ce que le premier enregistrement correspondant soit trouvé).

S'il existe de nombreux enregistrements dans b qui ont la même valeur col, vous perdrez également beaucoup de mémoire pour la lecture de tous ces enregistrements dans un espace temporaire, simplement pour constater que votre condition est satisfaite. Avec existe cela peut être généralement évité.

J'ai souvent trouvé EXISTS plus rapide que IN, même s’il existe un index. Cela dépend du système de base de données (l'optimiseur), des données et surtout du type d'index utilisé.

3
S.Roeper

Chaque implémentation de la base de données mais vous pouvez probablement deviner qu’elles résolvent toutes des problèmes communs plus ou moins de la même manière. Si vous utilisez MSSQL, examinez le plan d'exécution généré. Vous pouvez le faire en activant le profileur et les plans d’exécution. Cela vous donnera une version texte lorsque vous exécuterez la commande.

Je ne suis pas sûr de la version de MSSQL que vous utilisez, mais vous pouvez en obtenir une version graphique dans SQL Server 2000 dans l’analyseur de requêtes. Je suis sûr que cette fonctionnalité se cache dans SQL Server Studio Manager dans les versions ultérieures.

Regardez le plan d'exeuction. Dans la mesure du possible, évitez les analyses de table, à moins bien sûr que votre table soit petite, auquel cas une analyse de table est plus rapide qu'un index. Consultez les différentes opérations de jointure générées par chaque scénario.

3
uriDium

L'optimiseur doit être suffisamment intelligent pour vous donner le même résultat dans les deux cas pour les requêtes normales. Vérifiez le plan d'exécution et ils devraient vous donner la même chose. S'ils ne le font pas, je considère normalement que JOIN est plus rapide. Cependant, tous les systèmes sont différents, vous devez donc profiler le code sur votre système pour en être sûr.

1
Joel Coehoorn