2012-12-13 10 views
11

Kiedy wykonać następujące zapytanie:Dlaczego INNER JOIN nie równa (! =) Wiszą na zawsze

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

uzyskać wynik w ciągu 2 sekund. Istnieje około 6 milionów rekordów w table2 i 1 milion rekordów w table1

table2.number i table1.number są indeksowane.

Teraz chcę uzyskać listę numerów, które nie istnieją. W ten sposób:

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

Trwa to wiecznie i wciąż wisi .. Jak naprawić?

+0

Pomyśl o ile zapisze każdy z milionów w tabeli 2, do którego się przyłączą w milionach tabel1. –

Odpowiedz

27

Powiedzmy twoje pierwsze INNER JOIN wraca 75% 1.000.000 wierszy w table1. Drugie zapytanie nie zwraca 250 000 innych wierszy, jak myślisz. Zamiast tego próbuje utworzyć produkt kartezjański i usunąć 750 000 pasujących wierszy. W ten sposób próbuje zwrócić 6 000 000 × 1 000 000 750 000 wierszy. To jest wybrzuszony zestaw wyników wiersza 6 12.

Prawdopodobnie chcesz to:

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

ta zwraca wierszy w table1 nie występuje w table2.

Możesz być także zainteresowany FULL OUTER JOIN:

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

ta zwraca wiersze w obu tabelach, które nie mają spotkanie na drugim stole.

6

Powód, dla którego to nie działa, powoduje, że w prosty sposób łączysz każdy wiersz tabeli1 z każdym wierszem z tabelą 2. Potrzebujesz jeszcze czegoś, z czym możesz się przyłączyć. Najlepszym sposobem na zrobienie tego jest lewe połączenie (co oznacza, że ​​dołączy on do tabeli1 bez względu na to, ale nie do tabeli 2), a następnie sprawdź, czy nie ma wpisu dla tabeli 2 z wartością null. Będziesz wtedy musiał zrobić to samo dla table2.

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

Dobra odpowiedź :-) –

0

Zamiast tego można użyć tej metody: select * from table1 LEFT JOIN tabela2 NA table2.number = table1.number GDZIE table2.number jest zerowy lub table1.number jest NULL