Es scheint mir, dass Sie dasselbe in einer SQL-Abfrage tun können, indem Sie entweder NOT EXISTS, NOT IN oder LEFT JOIN WHERE IS NULL verwenden. Beispielsweise:
SELECT a FROM table1 WHERE a NOT IN (SELECT a FROM table2)
SELECT a FROM table1 WHERE NOT EXISTS (SELECT * FROM table2 WHERE table1.a = table2.a)
SELECT a FROM table1 LEFT JOIN table2 ON table1.a = table2.a WHERE table1.a IS NULL
Ich bin nicht sicher, ob ich die gesamte Syntax richtig verstanden habe, aber dies sind die allgemeinen Techniken, die ich gesehen habe. Warum sollte ich mich dafür entscheiden, eins über das andere zu verwenden? Unterscheidet sich die Leistung ...? Welches davon ist das schnellste / effizienteste? (Wenn es von der Implementierung abhängt, wann würde ich jeden verwenden?)
EXISTS
Klausel zurückgeben. Sie können zurückkehren*
,NULL
oder was auch immer: alles wird optimiert entfernt werden.SELECT
und zu setzenFROM
. Und*
ist einfach einfacher zu tippen. Ja,SQL
hat Ähnlichkeit mit einer natürlichen Sprache, aber sie wird von einer Maschine, einer programmierten Maschine, analysiert und ausgeführt. Es ist nicht so, dass es jemals plötzlich in Ihre Kabine eindringen wird und "EXISTS
Hör auf, nach den zusätzlichen Feldern in einer Abfrage zu fragen, weil ich es satt habe, sie zu analysieren und sie dann wegzuwerfen!". Mit einem Computer ist das wirklich in Ordnung.Antworten:
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
In einer Nussschale:
NOT IN
ist ein bisschen anders: Es stimmt nie überein, wenn es nur eine einzigeNULL
in der Liste gibt.In
MySQL
,NOT EXISTS
ist ein bisschen weniger effizientIn
SQL Server
,LEFT JOIN / IS NULL
ist weniger effizientIn
PostgreSQL
,NOT IN
ist weniger effizientIn
Oracle
sind alle drei Methoden gleich.quelle
table1 .a
enthält, diese Zeile nicht zurückgegeben wird, die Abfrage jedoch leer ist. NOT IN vs. NOT EXISTS Nullable Columns: SQL ServerNULL
EXISTS
NOT IN
table2
NULL NOT IN ()
als wahr (nichtNULL
) ausgewertet , genau wieNOT EXISTS (NULL = column)
NOT EXISTS
gibt die Zeile immer zurück,NOT IN
tut dies jedoch nur, wenn die Unterabfrage keine Zeilen zurückgibt.Wenn die Datenbank die Abfrage gut optimieren kann, werden die beiden ersten in etwas nahe der dritten umgewandelt.
Für einfache Situationen wie die in Ihrer Frage sollte es keinen oder nur einen geringen Unterschied geben, da alle als Joins ausgeführt werden. Bei komplexeren Abfragen kann die Datenbank möglicherweise keinen Join aus den Abfragen
not in
undnot exists
erstellen. In diesem Fall werden die Abfragen viel langsamer. Auf der anderen Seite kann ein Join auch eine schlechte Leistung erbringen, wenn kein Index verwendet werden kann. Nur weil Sie einen Join verwenden, bedeutet dies nicht, dass Sie sicher sind. Sie müssten den Ausführungsplan der Abfrage überprüfen, um festzustellen, ob möglicherweise Leistungsprobleme vorliegen.quelle
Angenommen, Sie vermeiden Nullen, dann sind dies alle Möglichkeiten, einen Anti-Join zu schreiben mit Standard SQL zu .
Eine offensichtliche Auslassung ist das Äquivalent mit
EXCEPT
:Hinweis: In Oracle müssen Sie den
MINUS
Operator verwenden (wahrscheinlich ein besserer Name):Apropos proprietäre Syntax: Abhängig von dem Produkt, das Sie verwenden, z. B.
OUTER APPLY
in SQL Server (etwa) , gibt es möglicherweise auch Nicht-Standard-Äquivalente, die untersucht werden sollten :quelle
Wenn Sie Daten in eine Tabelle mit einem Primärschlüssel mit mehreren Feldern einfügen müssen, denken Sie daran, dass es viel schneller sein wird (ich habe in Access versucht, aber ich denke in jeder Datenbank), nicht zu überprüfen, ob "keine Datensätze mit 'solchen' Werten in der Tabelle vorhanden sind". - lieber einfach in die Tabelle einfügen, und überschüssige Datensätze (mit dem Schlüssel) werden nicht zweimal eingefügt.
quelle
In der Leistungsperspektive wird immer die Verwendung inverser Schlüsselwörter wie NOT IN, NOT EXISTS, ... vermieden. Um die inversen Elemente zu überprüfen, muss DBMS alle verfügbaren Elemente durchlaufen und die inverse Auswahl löschen.
quelle
NOT
?