Quelle est la différence entre la clause EXISTS
et IN
dans SQL?
Quand devrions-nous utiliser EXISTS
et quand devrions-nous utiliser IN
?
Le exists
mot-clé peut être utilisé de cette façon, mais il est vraiment destiné à éviter de compter:
--this statement needs to check the entire table
select count(*) from [table] where ...
--this statement is true as soon as one match is found
exists ( select * from [table] where ... )
C'est très utile lorsque vous avez des if
instructions conditionnelles, car cela exists
peut être beaucoup plus rapide que count
.
Le in
mieux est utilisé lorsque vous avez une liste statique à transmettre:
select * from [table]
where [field] in (1, 2, 3)
Lorsque vous avez un tableau dans une in
instruction, il est plus logique d'utiliser un join
, mais surtout cela ne devrait pas avoir d'importance. L'optimiseur de requêtes doit renvoyer le même plan dans les deux cas. Dans certaines implémentations (généralement plus anciennes, telles que Microsoft SQL Server 2000), les in
requêtes obtiendront toujours un plan de jointure imbriqué , tandis que les join
requêtes utiliseront imbriqué, fusionner ou hacher selon le cas. Des implémentations plus modernes sont plus intelligentes et peuvent ajuster le plan même lorsqu'il in
est utilisé.
JOIN
en remplacement deIN
.select * from [table] where [field] in (select [field] from [table2])
renvoie les mêmes résultats (et plan de requête) queselect * from [table] join [table2] on [table2].[field] = [table].[field]
.table
, tandis que la seconde renvoie tout detable
ettable2
. Dans certaines bases de données SQL (pour la plupart plus anciennes), lain
requête sera implémentée en tant que jointure imbriquée, tandis que lajoin
requête peut être imbriquée, fusionnée, hachée, etc. - ce qui est le plus rapide.exists
peuvent être utilisés dans une déclaration de cas, ils peuvent donc être utiles de cette façon, c'estselect case when exists (select 1 from emp where salary > 1000) then 1 else 0 end as sal_over_1000
EXISTS
vous indiquera si une requête a renvoyé des résultats. par exemple:IN
est utilisé pour comparer une valeur à plusieurs, et peut utiliser des valeurs littérales, comme ceci:Vous pouvez également utiliser des résultats de requête avec la
IN
clause, comme ceci:la source
Basé sur l' optimiseur de règles :
EXISTS
est beaucoup plus rapide queIN
lorsque les résultats de la sous-requête sont très importants.IN
est plus rapide queEXISTS
lorsque les résultats de la sous-requête sont très petits.Basé sur l' optimiseur de coûts :
la source
Je suppose que vous savez ce qu'ils font et que vous les utilisez donc différemment, je vais donc comprendre votre question comme suit: quand serait-ce une bonne idée de réécrire le SQL pour utiliser IN au lieu d'EXISTS, ou vice versa.
Est-ce une hypothèse juste?
Edit : La raison pour laquelle je demande est que dans de nombreux cas, vous pouvez réécrire un SQL basé sur IN pour utiliser un EXISTS à la place, et vice versa, et pour certains moteurs de base de données, l'optimiseur de requête traitera les deux différemment.
Par exemple:
peut être réécrit en:
ou avec une jointure:
Donc ma question est toujours d'actualité, est-ce que l'affiche originale se demande ce que fait IN et EXISTS, et donc comment l'utiliser, ou demande-t-il si la réécriture d'un SQL utilisant IN pour utiliser EXISTS à la place, ou vice versa, sera une bonne idée?
la source
JOIN
, vous aurez besoin d'unDISTINCT
EXISTS
est beaucoup plus rapide queIN
lorsque les résultats de la sous-requête sont très importants.IN
est plus rapide queEXISTS
lorsque les résultats de la sous-requête sont très petits.Requête 1
Requête 2
Si
t1
votre identifiant a une valeur nulle, la requête 1 les trouvera, mais la requête 2 ne trouvera pas de paramètres nuls.Je veux dire
IN
ne peut rien comparer avec null, donc il n'a aucun résultat pour null, maisEXISTS
peut tout comparer avec null.la source
Si vous utilisez l'
IN
opérateur, le moteur SQL analysera tous les enregistrements extraits de la requête interne. D'un autre côté, si nous utilisonsEXISTS
, le moteur SQL arrêtera le processus d'analyse dès qu'il aura trouvé une correspondance.la source
IN prend uniquement en charge les relations d'égalité (ou l'inégalité lorsqu'elle est précédée de NOT ).
C'est un synonyme de = any / = some , eg
EXISTS prend en charge différents types de relations, qui ne peuvent pas être exprimées à l'aide de IN , par exemple -
Et sur une note différente -
Les prétendues performances et les différences techniques entre EXISTS et IN peuvent résulter d'implémentations / limitations / bogues spécifiques de fournisseurs, mais bien souvent, ce ne sont que des mythes créés en raison du manque de compréhension des bases de données internes.
La définition des tables, la précision des statistiques, la configuration de la base de données et la version de l'optimiseur ont tous un impact sur le plan d'exécution et donc sur les mesures de performance.
la source
Le
Exists
mot clé évalue vrai ou faux, mais leIN
mot clé compare toutes les valeurs dans la colonne de sous-requête correspondante. Un autreSelect 1
peut être utilisé avec laExists
commande. Exemple:Mais
IN
est moins efficace doncExists
plus rapide.la source
Je pense,
EXISTS
c'est lorsque vous devez faire correspondre les résultats de la requête avec une autre sous-requête. Les résultats de la requête n ° 1 doivent être récupérés là où les résultats de la sous-requête correspondent. Type de jointure. Par exemple, sélectionnez le tableau des clients n ° 1 qui a également passé le tableau des commandes n ° 2IN est à récupérer si la valeur d'une colonne spécifique se trouve dans
IN
une liste (1, 2, 3, 4, 5).Quand utiliser l'un par rapport à l'autre ... quand vous sentez qu'il se lit correctement (communique mieux l'intention).
la source
La différence réside ici:
La requête ci-dessus renverra tous les enregistrements tandis que celle ci-dessous retournera vide.
Essayez-le et observez la sortie.
la source
Selon ma connaissance, lorsqu'une sous-requête renvoie une
NULL
valeur, alors l'instruction entière devientNULL
. Dans ce cas, nous utilisons leEXITS
mot - clé. Si nous voulons comparer des valeurs particulières dans des sous-requêtes, nous utilisons leIN
mot - clé.la source
Laquelle est la plus rapide dépend du nombre de requêtes récupérées par la requête interne:
EXIST évalue sur vrai ou faux mais IN compare plusieurs valeurs. Lorsque vous ne savez pas que l'enregistrement existe ou non, vous devez choisir EXIST.
la source
La raison en est que l'opérateur EXISTS fonctionne selon le principe «au moins trouvé». Il retourne vrai et arrête l'analyse du tableau une fois qu'au moins une ligne correspondante a été trouvée.
D'autre part, lorsque l'opérateur IN est combiné avec une sous-requête, MySQL doit d'abord traiter la sous-requête, puis utilise le résultat de la sous-requête pour traiter la requête entière.
la source
Ma compréhension est que les deux devraient être les mêmes tant que nous n'avons pas affaire à des valeurs NULL.
La même raison pour laquelle la requête ne renvoie pas la valeur pour = NULL vs est NULL. http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/
En ce qui concerne l'argument booléen vs comparateur, pour générer un booléen, les deux valeurs doivent être comparées et c'est ainsi que fonctionne une condition, donc je n'arrive pas à comprendre comment IN et EXISTS se comportent différemment.
la source
In certain circumstances, it is better to use IN rather than EXISTS. In general, if the selective predicate is in the subquery, then use IN. If the selective predicate is in the parent query, then use EXISTS.
https://docs.oracle.com/cd/B19306_01/server.102/b14211/sql_1016.htm#i28403
la source
Si une sous-requête renvoie plusieurs valeurs, vous devrez peut-être exécuter la requête externe - si les valeurs de la colonne spécifiée dans la condition correspondent à n'importe quelle valeur du jeu de résultats de la sous-requête. Pour effectuer cette tâche, vous devez utiliser le
in
mot - clé.Vous pouvez utiliser une sous-requête pour vérifier si un ensemble d'enregistrements existe. Pour cela, vous devez utiliser la
exists
clause avec une sous-requête. Leexists
mot clé renvoie toujours une valeur vraie ou fausse.la source
Je crois que cela a une réponse simple. Pourquoi ne le vérifiez-vous pas auprès des personnes qui ont développé cette fonction dans leurs systèmes?
Si vous êtes un développeur MS SQL, voici la réponse directement de Microsoft.
IN
:EXISTS
:la source
J'ai trouvé que l'utilisation du mot clé EXISTS est souvent très lente (c'est très vrai dans Microsoft Access). J'utilise plutôt l'opérateur de jointure de cette manière: devrais-je-utiliser-le-mot-clé-existe-dans-sql
la source
EXISTS est plus rapide en performances qu'en IN. Si la plupart des critères de filtrage sont dans la sous-requête, il vaut mieux utiliser IN et si la plupart des critères de filtrage sont dans la requête principale, il vaut mieux utiliser EXISTS.
la source
Si vous utilisez l'opérateur IN, le moteur SQL analysera tous les enregistrements extraits de la requête interne. D'un autre côté, si nous utilisons EXISTS, le moteur SQL arrêtera le processus d'analyse dès qu'il trouvera une correspondance.
la source
IN
etEXISTS
peuvent être équivalents et transformés les uns dans les autres.