2012-12-13 7 views
11

Wenn ich die folgende Abfrage ausführen:Warum INNER JOIN nicht gleich (! =) Hängen immer

SELECT * FROM `table1` 
INNER JOIN table2 ON table2.number = table1.number 

ich innerhalb von 2 Sekunden erhalten Sie das Ergebnis. Es gibt etwa 6 Millionen Datensätze in table2 und 1 Million Datensätze in table1

table2.number und table1.number sind indexiert.

Jetzt möchte ich eine Liste von Zahlen, die nicht existieren. Gefällt mir:

SELECT * FROM `table1` 
INNER JOIN table2 ON table2.number != table1.number 

Es dauert ewig und immer noch hängen .. Wie zu beheben?

+0

Denken Sie darüber nach, wie viele zeichnet jeden der Millionen in Tabelle2 auf, die zu den Millionen von Tabelle1 hinzugefügt werden. –

Antwort

27

Ihre ersten INNER JOIN Renditen 75% der 1.000.000 Zeilen in table1 sagen lassen. Die zweite Abfrage gibt die 250.000 anderen Zeilen nicht zurück, wie Sie denken. Stattdessen wird versucht, ein kartesisches Produkt zu erstellen und die 750.000 übereinstimmenden Zeilen zu entfernen. So versucht es 6.000.000 × 1.000.000-750.000 Zeilen zurückzugeben. Das ist ein ausgewogener Zeilenergebnissatz. 6

Sie wollen wahrscheinlich diese:

SELECT * FROM table1 
LEFT JOIN table2 ON table2.number = table1.number 
WHERE table2.number IS NULL 

Dies gibt Zeilen in table1 nicht in table2.

könnten Sie auch FULL OUTER JOIN interessieren:

SELECT * FROM table1 
FULL OUTER JOIN table2 ON table2.number = table1.number 
WHERE table1.number IS NULL AND table2.number IS NULL 

Dies gibt Zeilen in beiden Tabellen, die auf der anderen Tabelle keine Übereinstimmung haben.

6

Der Grund, warum dies nicht funktioniert, ist, dass Sie grundsätzlich jede Zeile von table1 mit jeder Zeile mit Tabelle 2 verbinden. Sie brauchen etwas, mit dem Sie sich noch verbinden können. Der beste Weg, dies zu tun, ist eine Linke Join zu machen (was bedeutet, dass Table1 verbunden wird, egal was, aber nicht Table2) und dann sicherstellen, dass es keinen Eintrag für table2 mit dem is null gibt. Sie müssen dann dasselbe für table2 tun.

SELECT * FROM `table1` 
LEFT JOIN table2 ON table2.number = table1.number 
WHERE table2.number is NULL 

UNION 

SELECT * FROM `table2` 
LEFT JOIN table1 ON table2.number = table1.number 
WHERE table1.number is NULL 
+0

Schöne Antwort :-) –

0

Statt dessen können Sie diese Methode verwenden: SELECT * FROM table1 LINKS table2 ON table2.number JOIN = table1.number WHERE table2.number NULL OR table1.number ist NULL