Mise à jour:
Ces articles dans mon blog décrire les différences entre les méthodes plus en détail:
Il y a trois façons de faire une telle requête:
-
LEFT JOIN / IS NULL
:
SELECT *
FROM common
LEFT JOIN
table1 t1
ON t1.common_id = common.common_id
WHERE t1.common_id IS NULL
-
NOT EXISTS
:
SELECT *
FROM common
WHERE NOT EXISTS
(
SELECT NULL
FROM table1 t1
WHERE t1.common_id = common.common_id
)
-
NOT IN
:
SELECT *
FROM common
WHERE common_id NOT IN
(
SELECT common_id
FROM table1 t1
)
Lors de l' table1.common_id
n'est pas nullable, toutes ces requêtes sont sémantiquement identiques.
Quand il est nullable, NOT IN
est différent, puisqu' IN
(et, par conséquent, NOT IN
) rendement NULL
lorsqu'une valeur ne correspond pas à quoi que ce soit dans une liste contenant un NULL
.
Cela peut être déroutant, mais peut devenir plus évident si nous nous rappelons la syntaxe alternative à cela:
common_id = ANY
(
SELECT common_id
FROM table1 t1
)
Le résultat de cette condition est un booléen produit de toutes les comparaisons à l'intérieur de la liste. Bien sûr, un seul NULL
de la valeur des rendements de l' NULL
résultat qui rend la totalité du résultat NULL
trop.
Nous n'avons jamais ne peut pas dire certainement que l' common_id
n'est pas égal à quoi que ce soit de cette liste, depuis au moins l'une des valeurs est - NULL
.
Supposons que nous disposons de ces données:
common
--
1
3
table1
--
NULL
1
2
LEFT JOIN / IS NULL
et NOT EXISTS
sera de retour 3
, NOT IN
sera de retour rien (puisqu'il sera toujours correspondre à la FALSE
ou NULL
).
En MySQL
, en cas de non-colonne nullable, LEFT JOIN / IS NULL
et NOT IN
sont un peu (quelques pour cent) plus efficace que l' NOT EXISTS
. Si la colonne est nullable, NOT EXISTS
est le plus efficace (encore une fois, pas beaucoup).
En Oracle
, tous les trois requêtes de rendement mêmes plans ( ANTI JOIN
).
En SQL Server
, NOT IN
/ NOT EXISTS
sont plus efficaces, car LEFT JOIN / IS NULL
ne peut pas être optimisé pour un ANTI JOIN
par son optimiseur.
En PostgreSQL
, LEFT JOIN / IS NULL
et NOT EXISTS
sont plus efficaces que d' NOT IN
, sinus, ils sont optimisés pour un Anti Join
, tandis que l' NOT IN
utilise hashed subplan
(ou même un simple subplan
si la sous-requête est trop grande pour le hachage)