Bijwerken:
Deze artikelen in mijn blog beschrijven de verschillen tussen de methoden in meer detail:
NOT INvs.NOT EXISTSvs.LEFT JOIN / IS NULL:SQL ServerNOT INvs.NOT EXISTSvs.LEFT JOIN / IS NULL:PostgreSQLNOT INvs.NOT EXISTSvs.LEFT JOIN / IS NULL:OracleNOT INvs.NOT EXISTSvs.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)