Aktualisierung:
Diese Artikel in meinem Blog beschreiben die Unterschiede zwischen den Methoden genauer:
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
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 )
Wenn table1.common_id nicht nullable ist, sind alle diese Abfragen semantisch gleich.
Wenn es nullfähig ist, NOT IN ist anders, da IN (und daher NOT IN ) gibt NULL zurück wenn ein Wert mit nichts in einer Liste übereinstimmt, die einen NULL enthält .
Das mag verwirrend sein, wird aber offensichtlicher, wenn wir uns an die alternative Syntax dafür erinnern:
common_id = ANY
(
SELECT common_id
FROM table1 t1
)
Das Ergebnis dieser Bedingung ist ein boolsches Produkt aller Vergleiche innerhalb der Liste. Natürlich ein einzelnes NULL value ergibt den NULL Ergebnis, das das gesamte Ergebnis NULL darstellt auch.
Wir können niemals definitiv sagen, dass common_id ist mit nichts aus dieser Liste gleich, da mindestens einer der Werte NULL ist .
Angenommen, wir haben diese Daten:
common
--
1
3
table1
--
NULL
1
2
LEFT JOIN / IS NULL und NOT EXISTS gibt 3 zurück , NOT IN gibt nichts zurück (da es immer entweder zu FALSE ausgewertet wird oder NULL ).
In MySQL , falls es sich um eine nicht nullfähige Spalte handelt, LEFT JOIN / IS NULL und NOT IN sind etwas (mehrere Prozent) effizienter als NOT EXISTS . Wenn die Spalte nullfähig ist, NOT EXISTS ist am effizientesten (wiederum nicht viel).
In Oracle , ergeben alle drei Abfragen dieselben Pläne (ein ANTI JOIN ).
In SQL Server , NOT IN / NOT EXISTS sind effizienter, da LEFT JOIN / IS NULL kann nicht auf einen ANTI JOIN optimiert werden durch seinen Optimierer.
In PostgreSQL , LEFT JOIN / IS NULL und NOT EXISTS sind effizienter als NOT IN , da sie auf einen Anti Join optimiert sind , während NOT IN verwendet hashed subplan (oder sogar ein einfacher subplan wenn die Unterabfrage zu groß zum Hashen ist)