Je suis curieux de savoir lequel des éléments suivants serait le plus efficace?
J'ai toujours été un peu prudent dans l'utilisation IN
car je pense que SQL Server transforme l'ensemble de résultats en une grande IF
déclaration. Pour un ensemble de résultats volumineux, cela peut entraîner de mauvaises performances. 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, ne serait-il pas EXISTS
plus efficace?
WHERE EXISTS (SELECT * FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)
contre.
WHERE bx.BoxID IN (SELECT BoxID FROM Base WHERE [Rank = 2])
sql-server
sql-server-2005
exists
query-performance
sql-in
Randy Minder
la source
la source
select 1 from Base...
fairewhere exists
puisque vous ne vous souciez pas réellement des résultats, juste qu'une ligne existe réellement.Réponses:
EXISTS
sera plus rapide car une fois que le moteur a trouvé un coup, il cessera de regarder car la condition s'est avérée vraie.Avec
IN
, il collectera tous les résultats de la sous-requête avant un traitement ultérieur.la source
La réponse acceptée est myope et la question un peu lâche en cela:
Je pense que l'optimiseur est suffisamment intelligent pour convertir entre "in" et "existe" lorsqu'il y a une différence de coût significative due à (1) et (2), sinon il peut simplement être utilisé comme un indice (par exemple, il existe pour encourager l'utilisation de un index recherché sur le côté droit).
Les deux formulaires peuvent être convertis en formulaires de jointure en interne, avoir l'ordre de jointure inversé et s'exécuter en tant que boucle, hachage ou fusion - en fonction du nombre de lignes estimé (gauche et droite) et de l'existence d'index à gauche, à droite ou des deux côtés.
la source
IN
etEXISTS
. Essayez de trouver tous les cas où ils n'obtiennent pas le même plan (bien que cela ne s'applique pas àNOT IN
etNOT EXISTS
)J'ai fait quelques tests sur SQL Server 2005 et 2008, et les EXISTS et IN reviennent avec exactement le même plan d'exécution réel, comme d'autres l'ont indiqué. L'optimiseur est optimal. :)
Cependant, il faut savoir que EXISTS, IN et JOIN peuvent parfois renvoyer des résultats différents si vous n'exprimez pas votre requête correctement: http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210 .aspx
la source
Il y a beaucoup de réponses trompeuses ici, y compris celle hautement votée (bien que je ne pense pas que leurs opérations signifiaient du mal). La réponse courte est: ce sont les mêmes.
Il existe de nombreux mots-clés dans le langage (T-) SQL, mais à la fin, la seule chose qui se passe réellement sur le matériel, ce sont les opérations telles qu'elles apparaissent dans le plan de requête d'exécution.
L'opération relationnelle (théorie mathématique) que nous faisons lorsque nous invoquons
[NOT] IN
et[NOT] EXISTS
est la semi-jointure (anti-jointure lors de l'utilisationNOT
). Ce n'est pas un hasard si les opérations sql-server correspondantes portent le même nom . Il n'y a aucune opération qui mentionneIN
ouEXISTS
n'importe où - seulement des (anti-) semi jointures. Ainsi, il n'y a aucun moyen qu'un choix deIN
vs logiquement équivalentEXISTS
puisse affecter les performances car il existe un seul et unique moyen, l'opération d'exécution (anti) semi-jointure, d'obtenir leurs résultats .Un exemple:
Requête 1 ( plan )
Requête 2 ( plan )
la source
J'irais avec EXISTS sur IN, voir le lien ci-dessous:
SQL Server: JOIN vs IN vs EXISTS - la différence logique
Crédit du blog: https://stackoverflow.com/users/31345/mladen-prajdic
la source
Les plans d'exécution seront généralement identiques dans ces cas, mais tant que vous ne verrez pas comment l'optimiseur prend en compte tous les autres aspects des index, etc., vous ne saurez jamais vraiment.
la source
Ainsi, IN n'est pas identique à EXISTS et ne produira pas le même plan d'exécution.
Habituellement, EXISTS est utilisé dans une sous-requête corrélée, ce qui signifie que vous rejoindrez la requête interne EXISTS avec votre requête externe. Cela ajoutera d'autres étapes pour produire un résultat car vous devez résoudre les jointures de requête externes et les jointures de requête internes, puis faire correspondre leurs clauses where pour joindre les deux.
En général, IN est utilisé sans corréler la requête interne avec la requête externe, et cela peut être résolu en une seule étape (dans le meilleur des cas).
Considère ceci:
Si vous utilisez IN et que le résultat de la requête interne est des millions de lignes de valeurs distinctes, il sera probablement plus lent que EXISTS étant donné que la requête EXISTS est performante (a les bons index à joindre avec la requête externe).
Si vous utilisez EXISTS et que la jointure avec votre requête externe est complexe (prend plus de temps à effectuer, pas d'index approprié), cela ralentira la requête du nombre de lignes dans la table externe, parfois le temps estimé pour terminer peut être en jours. Si le nombre de lignes est acceptable pour votre matériel donné, ou si la cardinalité des données est correcte (par exemple moins de valeurs DISTINCT dans un grand ensemble de données), IN peut fonctionner plus rapidement que EXISTS.
Tout ce qui précède sera noté lorsque vous avez une bonne quantité de lignes sur chaque table (par juste, je veux dire quelque chose qui dépasse votre traitement CPU et / ou les seuils de RAM pour la mise en cache).
Donc, la RÉPONSE est-elle DÉPEND. Vous pouvez écrire une requête complexe dans IN ou EXISTS, mais en règle générale, vous devriez essayer d'utiliser IN avec un ensemble limité de valeurs distinctes et EXISTS lorsque vous avez beaucoup de lignes avec beaucoup de valeurs distinctes.
L'astuce consiste à limiter le nombre de lignes à analyser.
Cordialement,
MarianoC
la source
Pour optimiser le
EXISTS
, soyez très littéral; quelque chose doit simplement être là, mais vous n'avez en fait pas besoin de données renvoyées par la sous-requête corrélée. Vous évaluez simplement une condition booléenne.Alors:
WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)
Étant donné que la sous-requête corrélée est
RBAR
, le premier appel de résultat rend la condition vraie et elle n'est plus traitée.la source
Du haut de ma tête et pas garanti d'être correct: je crois que le second sera plus rapide dans ce cas.
IN
court-circuitera dès qu'il trouve une correspondance.la source