Opdatering:
Disse artikler i min blog beskriver forskellene mellem metoderne mere detaljeret:
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
Der er tre måder at udføre sådan en forespørgsel på:
-
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 )
Når table1.common_id er ikke nullbar, er alle disse forespørgsler semantisk ens.
Når den er nullbar, NOT IN er anderledes, da IN (og derfor NOT IN ) returner NULL når en værdi ikke matcher noget på en liste, der indeholder en NULL .
Dette kan være forvirrende, men kan blive mere indlysende, hvis vi husker den alternative syntaks for dette:
common_id = ANY
(
SELECT common_id
FROM table1 t1
)
Resultatet af denne tilstand er et boolsk produkt af alle sammenligninger på listen. Selvfølgelig en enkelt NULL værdien giver NULL resultat, som gengiver hele resultatet NULL også.
Vi kan aldrig sige bestemt, at common_id er ikke lig med noget fra denne liste, da mindst én af værdierne er NULL .
Antag, at vi har disse data:
common
--
1
3
table1
--
NULL
1
2
LEFT JOIN / IS NULL og NOT EXISTS returnerer 3 , NOT IN returnerer intet (da det altid vil evaluere til enten FALSE eller NULL ).
I MySQL , i tilfælde af ikke-nulbar kolonne, LEFT JOIN / IS NULL og NOT IN er en lille smule (adskillige procent) mere effektive end NOT EXISTS . Hvis kolonnen er nullbar, NOT EXISTS er den mest effektive (igen, ikke meget).
I Oracle , giver alle tre forespørgsler samme planer (en ANTI JOIN ).
I SQL Server , NOT IN / NOT EXISTS er mere effektive, da LEFT JOIN / IS NULL kan ikke optimeres til en ANTI JOIN af dens optimizer.
I PostgreSQL , LEFT JOIN / IS NULL og NOT EXISTS er mere effektive end NOT IN , sine er de optimeret til en Anti Join , mens NOT IN bruger hashed subplan (eller endda en almindelig subplan hvis underforespørgslen er for stor til at hash)