141 votes

Performances de SQL Server IN vs. EXISTS

Je suis curieux de savoir laquelle des propositions suivantes serait la plus efficace ?

J'ai toujours été un peu prudent sur le fait d'utiliser IN parce que je crois que SQL Server transforme l'ensemble des résultats en un gros IF déclaration. Pour un grand ensemble de résultats, cela pourrait entraîner des performances médiocres. Pour les petits ensembles de résultats, je ne suis pas sûr que l'un ou l'autre soit préférable. Pour les grands ensembles de résultats, est-ce que EXISTS être plus efficace ?

WHERE EXISTS (SELECT * FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)

vs.

WHERE bx.BoxID IN (SELECT BoxID FROM Base WHERE [Rank = 2])

9 votes

La meilleure façon de le savoir est de l'essayer et de faire quelques mesures.

11 votes

Il y a obtenu Il doit y avoir des milliards de copies de ce site .......

0 votes

@marc_s : oui, mais je pense que cela dépend vraiment du cas. Je suppose que la réponse canonique est celle de Klausbyskov (ou de quiconque peut revendiquer l'art antérieur).

168voto

keithwarren7 Points 6672

EXISTS sera plus rapide car une fois que le moteur a trouvé une correspondance, il cessera de chercher car la condition s'est avérée vraie.

Avec IN il collectera tous les résultats de la sous-requête avant de poursuivre le traitement.

87 votes

C'était vrai auparavant, mais dans les versions actuelles (au moins 2008), l'optimiseur est beaucoup plus intelligent... il traite en fait IN () comme EXISTS ().

14 votes

@Aaron - oui, généralement l'optimiseur produira en interne un meilleur plan. Cependant, s'appuyer sur des raccourcis internes pourrait être préjudiciable dans des scénarios plus complexes.

0 votes

C'est étrange. Alors que le plan de requête est exactement le même pour les deux pour une de mes requêtes, l'explication montre un nombre de lignes de 972 pour IN et 959 pour EXIST. Tout le reste est identique. Je suis sous Mysql 5.1.42, il se peut donc que ce soit simplement ancien.

39voto

Adam Nofsinger Points 1680

J'ai effectué quelques tests sur SQL Server 2005 et 2008, et tant pour les EXISTS que pour les IN, le plan d'exécution réel est exactement le même, comme d'autres l'ont indiqué. L'Optimiseur est optimal :)

Il faut cependant savoir que les expressions EXISTS, IN et JOIN peuvent parfois donner des résultats différents si vous ne formulez pas votre requête correctement : http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210.aspx

9voto

Tanner Points 6058

J'opterais pour EXISTS plutôt que IN, voir le lien ci-dessous :

SQL Server : JOIN vs IN vs EXISTS - la différence logique

On pense souvent à tort que IN se comporte de la même manière que EXISTS ou JOIN en termes de résultats retournés. C'est tout simplement faux.

IN : Renvoie un message vrai si une valeur spécifiée correspond à une valeur quelconque dans une sous-requête ou une liste.

Existe : Renvoie un résultat positif si une sous-requête contient des lignes.

Rejoignez-nous : Joint 2 ensembles de résultats sur la colonne de jonction.

Crédit blog : https://stackoverflow.com/users/31345/mladen-prajdic

4voto

Cade Roux Points 53870

Les plans d'exécution seront généralement identiques dans ces cas, mais tant que vous n'aurez pas vu comment l'optimiseur prend en compte tous les autres aspects (index, etc.), vous ne le saurez jamais.

0 votes

Quand je lis que l'optimiseur est bon, je pense toujours que dans mon cas précis, il échouera.

0voto

Kumar Manish Points 1270

Le WHERE IN est en fait converti en un INNER JOIN par l'optimiseur et est traité exactement de la même manière par l'optimiseur. Laissés à eux-mêmes, j'ai constaté que les développeurs écriront incorrectement des jointures imbriquées triples et quadruples s'ils sont autorisés à utiliser WHERE IN de manière régulière, car il est facile pour eux de lire les graves problèmes de performance qui en résultent.

WHERE EXISTS n'est pas... WHERE EXISTS crée une forme de RBAR connue sous le nom de CORRELATED SUB-QUERY. Si elle est écrite correctement, elle est aussi assez rapide mais je n'autorise pas les gens à l'utiliser dans mon atelier parce qu'elle fait paraître le plan d'exécution particulièrement efficace (affiche le plan pour la première ligne seulement) alors qu'il ne l'est pas (il y a de rares exceptions dans 2k mais jamais nécessaire dans 2k5). Les développeurs voient cela et commencent à l'utiliser partout pour chaque jointure interne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X