13 Stimmen

Was ist schneller - NOT IN oder NOT EXISTS?

Ich habe eine Insert-Select-Anweisung, die nur Zeilen einfügen muss, bei denen ein bestimmter Bezeichner der Zeile in keiner der beiden anderen Tabellen vorhanden ist. Welche der folgenden Möglichkeiten wäre schneller?

INSERT INTO Table1 (...)
SELECT (...) FROM Table2 t2
WHERE ...
   AND NOT EXISTS (SELECT 'Y' from Table3 t3 where t2.SomeFK = t3.RefToSameFK)
   AND NOT EXISTS (SELECT 'Y' from Table4 t4 where t2.SomeFK = t4.RefToSameFK AND ...)

... oder...

INSERT INTO Table1 (...)
SELECT (...) FROM Table2 t2
WHERE ...
   AND t2.SomeFK NOT IN (SELECT RefToSameFK from Table3)
   AND t2.SomeFK NOT IN (SELECT RefToSameFK from Table4 WHERE ...)

... oder leisten sie ungefähr dasselbe? Gibt es außerdem eine andere Möglichkeit, diese Abfrage zu strukturieren, die vorzuziehen wäre? Ich mag Unterabfragen im Allgemeinen nicht, da sie der Abfrage eine weitere "Dimension" hinzufügen, die die Laufzeit um polynomiale Faktoren erhöht.

14voto

gpeche Punkte 21130

Normalerweise spielt es keine Rolle, ob NOT IN ist langsamer/schneller als NOT EXISTS denn sie sind ノット gleichwertig in Anwesenheit von NULL . Lesen:

NOT IN vs. NOT EXISTS

In diesen Fällen wollen Sie fast immer NOT EXISTS weil es das üblicherweise erwartete Verhalten aufweist.

Wenn sie gleichwertig sind, ist es wahrscheinlich, dass Ihre Datenbank das bereits herausgefunden hat und für beide den gleichen Ausführungsplan erstellt.

In den wenigen Fällen, in denen beide Optionen gleichwertig sind und Ihre Datenbank nicht in der Lage ist, dies herauszufinden, ist es besser, beide Ausführungspläne zu analysieren und die beste Option für Ihren speziellen Fall zu wählen.

1voto

Mark Sherretta Punkte 10050

Sie könnten einen LEFT OUTER JOIN verwenden und prüfen, ob der Wert in der Tabelle RIGHT NULL ist. Wenn der Wert NULL ist, ist die Zeile nicht vorhanden. Dies ist eine Möglichkeit, Unterabfragen zu vermeiden.

SELECT (...) FROM Table2 t2
LEFT OUTER JOIN t3 ON (t2.someFk = t3.ref)
WHERE t3.someField IS NULL

1voto

Larry Lustig Punkte 47313

Das hängt von der Größe der Tabellen, den verfügbaren Indizes und der Kardinalität dieser Indizes ab.

Wenn Sie nicht den gleichen Ausführungsplan für beide Abfragen erhalten und wenn keine der beiden Abfragen einen JOIN anstelle einer Unterabfrage plant, dann würde ich vermuten, dass Version 2 schneller ist. Version eins ist korreliert und würde daher viel mehr Unterabfragen erzeugen, Version zwei kann mit insgesamt drei Abfragen zufrieden sein.

(Beachten Sie auch, dass verschiedene Motoren in die eine oder andere Richtung tendieren können. Einige Suchmaschinen können korrekt feststellen, dass die Abfragen gleich sind (wenn sie wirklich son dasselbe) und führen zu demselben Ausführungsplan).

0voto

David Castro Punkte 1417

Für größere Tabellen wird die Verwendung von NOT EXISTS/EXISTS empfohlen, da die IN-Klausel die Unterabfrage je nach Architektur der Tabellen sehr oft ausführt.

Basierend auf dem Kostenoptimierer:

Es gibt keinen Unterschied.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X