Aktualisieren:
Diese Artikel in meinem Blog beschreiben die Unterschiede zwischen den Methoden ausführlicher:
Es gibt drei Möglichkeiten, eine solche Abfrage durchzuführen:
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
)
Wann table1.common_id
nicht nullbar, sind alle diese Abfragen semantisch gleich.
Wenn es nullbar ist, NOT IN
ist es anders, da IN
(und daher NOT IN
) zurückgegeben wird, NULL
wenn ein Wert mit nichts in einer Liste übereinstimmt, die a enthältNULL
.
Dies mag verwirrend sein, kann aber offensichtlicher werden, wenn wir uns an die alternative Syntax erinnern:
common_id = ANY
(
SELECT common_id
FROM table1 t1
)
Das Ergebnis dieser Bedingung ist ein boolesches Produkt aller Vergleiche innerhalb der Liste. Natürlich NULL
ergibt ein einzelner Wert das NULL
Ergebnis, das auch das gesamte Ergebnis NULL
wiedergibt.
Wir können niemals definitiv sagen, dass common_id
dies nichts aus dieser Liste entspricht, da mindestens einer der Werte ist NULL
.
Angenommen, wir haben diese Daten:
common
--
1
3
table1
--
NULL
1
2
LEFT JOIN / IS NULL
und NOT EXISTS
wird zurückkehren 3
, NOT IN
wird nichts zurückgeben (da es immer entweder FALSE
oder auswerten wird NULL
).
In MySQL
, falls in nicht nullbaren Spalten, LEFT JOIN / IS NULL
und NOT IN
sind ein wenig (mehrere Prozent) effizienter als NOT EXISTS
. Wenn die Spalte nullbar ist,NOT EXISTS
ist sie am effizientesten (wiederum nicht viel).
In ergeben Oracle
alle drei Abfragen die gleichen Pläne (an ANTI JOIN
).
In SQL Server
, NOT IN
/ NOT EXISTS
sind effizienter, da LEFT JOIN / IS NULL
es ANTI JOIN
durch seinen Optimierer nicht zu einem optimiert werden kann.
In PostgreSQL
, LEFT JOIN / IS NULL
und NOT EXISTS
sind effizienter als NOT IN
sine sie auf eine optimierte Anti Join
, während NOT IN
Anwendungen hashed subplan
(oder auch eine einfache , subplan
wenn die Unterabfrage zu groß , um Hash ist)