Effizienter Weg, um wählen Sie alle Werte von einer Spalte nicht in einer anderen Spalte
Brauche ich, um alle Werte aus colA
sind nicht in colB
aus mytable
. Ich bin mit:
SELECT DISTINCT(colA) FROM mytable WHERE colA NOT IN (SELECT colB FROM mytable)
Es funktioniert jedoch die Abfrage der Einnahme zu lange, um abzuschließen.
Ist es ein effizienter Weg, dies zu tun?
NOT IN
verlangsamt, wie die Größe wächst, und es gibt oft ein limit, wie viele Zeilen können in derNOT IN
- Klausel. Außerhalb der kleinen Ergebnis-sets die ich gefunden habe, ist es besser, andere Mittel, um den Unterschied zwischen zwei Ergebnismengen.- Beim sprechen über Leistung, müssen Sie den Namen Ihres RDBMS oder bekommen suboptimale Antworten.
Du musst angemeldet sein, um einen Kommentar abzugeben.
In standard-SQL gibt es keine Klammern in
DISTINCT colA
.DISTINCT
ist nicht eine Funktion.Hinzugefügt
DISTINCT
zu der sub-select als gut. Wenn Sie viele Duplikate, könnte es beschleunigt die Abfrage.CTE könnte schneller sein, je nach DBMS. Ich darüber hinaus zeigen
LEFT JOIN
als alternative ausschließen, die Werte invalB
, und eine alternative Möglichkeit, um bestimmte Werte mitGROUP BY
:Oder, noch weiter vereinfacht und mit einer einfachen Unterabfrage (vermutlich die Schnellste):
Gibt es grundsätzlich 4 Techniken ausschließen von Zeilen mit Tasten vorhanden, die in einem anderen (oder derselben) Tabelle:
Der entscheidende Faktor für die Geschwindigkeit wird Indizes. Sie müssen Indizes auf
colA
undcolB
für diese Abfrage schnell sein.SELECT DISTINCT m1.colA FROM mytable m1 LEFT JOIN mytable m2 ON (m1.colA = m2.colB) WHERE m2.colA IS NULL ORDER BY m1.colA ASC
und es ist mehrere Größenordnungen schneller und scheint zu funktionieren - ist dies äquivalent zu dem code, den ich gepostet in der Frage? Es ist so viel schneller, dass ich bin misstrauisch, ich könnte etwas verpasst haben.WHERE m2.colB IS NULL
. Die (korrigierten) Abfrage könnte schneller sein, mitLEFT JOIN (SELECT DISTINCT colB FROM mytable) m2 ON m2.colB = m1.colA
wenn es gibt viele doppelte Werte fürcolB
.NULL
wennm2.colB
ist NULL hier, aberm2.colA
NULL sein kann, auch wennm2.colB
ist nicht. Also richtige (und schnellere!) form ist hier:WHERE m2.colB IS NULL
. WenncolA
definiert ist, NICHT NULL ist, dann ist deine Abfrage richtig ist.NULL
Werte. Wissen Sie, warum es ist so viel schneller?DISTINCT
änderung, die Sie vorgeschlagen, und es vervollständigt nun in wenigen Sekunden.Können Sie
exists
:exists
hat einen semi-join zu schnell mit den Werten.not in
rundet das ganze ResultSet und führt dann eineor
auf Sie.exists
ist in der Regel schneller für Werte in Tabellen.colA
s, wo es keine Zeile ausmytable
dasscolB
ist gleichcolA
.Können Sie die
AUßER
Betreiber, die effektiv diffs zweiSELECT
Abfragen.EXCEPT DISTINCT
zurück, so dass nur einzigartige Werte. OracleMINUS
- operator entsprichtEXCEPT DISTINCT
.