Bijwerken:
Deze artikelen in mijn blog beschrijven de verschillen tussen de methoden in meer detail:
NOT IN
vs.NOT EXISTS
vs.LEFT JOIN / IS NULL
:SQL Server
NOT IN
vs.NOT EXISTS
vs.LEFT JOIN / IS NULL
:PostgreSQL
NOT IN
vs.NOT EXISTS
vs.LEFT JOIN / IS NULL
:Oracle
NOT IN
vs.NOT EXISTS
vs.LEFT JOIN / IS NULL
:MySQL
Er zijn drie manieren om zo'n zoekopdracht uit te voeren:
-
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 )
Wanneer table1.common_id
is niet nullable, al deze zoekopdrachten zijn semantisch hetzelfde.
Als het nullable is, NOT IN
is anders, aangezien IN
(en daarom NOT IN
) retourneer NULL
wanneer een waarde niet overeenkomt met iets in een lijst met een NULL
.
Dit kan verwarrend zijn, maar kan duidelijker worden als we ons de alternatieve syntaxis hiervoor herinneren:
common_id = ANY
(
SELECT common_id
FROM table1 t1
)
Het resultaat van deze voorwaarde is een booleaans product van alle vergelijkingen in de lijst. Natuurlijk, een enkele NULL
waarde geeft de NULL
resultaat dat het hele resultaat NULL
weergeeft ook.
We kunnen nooit met zekerheid zeggen dat common_id
is niet gelijk aan iets uit deze lijst, aangezien ten minste één van de waarden NULL
. is .
Stel dat we deze gegevens hebben:
common
--
1
3
table1
--
NULL
1
2
LEFT JOIN / IS NULL
en NOT EXISTS
retourneert 3
, NOT IN
retourneert niets (aangezien het altijd zal evalueren naar FALSE
of NULL
).
In MySQL
, in het geval op een niet-nullable kolom, LEFT JOIN / IS NULL
en NOT IN
zijn een klein beetje (enkele procenten) efficiënter dan NOT EXISTS
. Als de kolom nullable is, NOT EXISTS
is het meest efficiënt (nogmaals niet veel).
In Oracle
, leveren alle drie de zoekopdrachten dezelfde plannen op (een ANTI JOIN
).
In SQL Server
, NOT IN
/ NOT EXISTS
zijn efficiënter, aangezien LEFT JOIN / IS NULL
kan niet worden geoptimaliseerd tot een ANTI JOIN
door zijn optimalisatieprogramma.
In PostgreSQL
, LEFT JOIN / IS NULL
en NOT EXISTS
zijn efficiënter dan NOT IN
, omdat ze zijn geoptimaliseerd voor een Anti Join
, terwijl NOT IN
gebruikt hashed subplan
(of zelfs een gewoon subplan
als de subquery te groot is om te hashen)