2013-03-18 14 views
27

Mam dwa następujące przykłady.SQL JOIN gdzie umieścić warunek WHERE?

1. Przykład (gdzie)

SELECT 1 
    FROM table1 t1 
    JOIN table2 t2 ON t1.id = t2.id 
WHERE t2.field = true 

2. Przykład (REJESTRACJA I)

SELECT 1 
    FROM table1 t1 
    JOIN table2 t2 ON t1.id = t2.id AND t2.field = true 

Jaki jest szybszy sposób pod względem wydajności? Co wolisz?

Odpowiedz

16

Jeśli filtr funkcjonalnie wejdzie w stan JOIN (tj. Jest faktycznym warunkiem połączenia, a nie tylko filtrem), musi pojawić się w klauzuli ON tego sprzężenia.

Warto zauważyć:

  • Jeśli umieścić go w klauzuli WHERE zamiast występy są takie same, czy przyłączyć się INNER, inaczej różni. Jak wspomniano w komentarzach, tak naprawdę nie ma znaczenia, ponieważ i tak wynik jest inny.

  • Umieszczenie filtra w klauzuli WHERE kiedy to naprawdę jest stan OUTER JOIN implicitely anuluje OUTER charakter warunku („Przyłącz się nawet wtedy, gdy nie ma zapisów”) jako filtry te sugerować, że musi być istniejące rekordy w pierwszym miejsce. Przykład:

... table1 t LEFT JOIN table2 u ON ... AND t2.column = 5 jest poprawna

... table1 t LEFT JOIN table2 u ON ... 
WHERE t2.column = 5 

jest błędne, gdyż t2.column = 5 opowiada silnik, który rejestruje od t2 są oczekiwane, która wykracza przeciwko zewnętrznym przyłączyć. Wyjątkiem od tej zasady będzie filtr IS NULL, jak WHERE t2.column IS (NOT) NULL (co jest w rzeczywistości w wygodny sposób do budowy łączy zewnętrzną warstwę warunkowy)

  • LEFT i RIGHT implicitely OUTER łączy się łączy.

Mam nadzieję, że pomogło.

+2

Ta odpowiedź zawiera błędne i pomieszane pisanie. 1. W przypadku INNER JOIN każdy warunek może być w WHERE zamiast ON, o ile nie ma interweniującego OUTER JOIN. 2. Podczas przenoszenia warunku LEFT JOIN z ON na WHERE wydajność nie ma znaczenia, ponieważ (jak mówisz) ogólnie wynik jest różny. 3. Ta różnica ogólnie nie "przekształca OUTER JOIN w INNER JOIN". – philipxy

+0

@philipxy masz rację, próbowałem trochę posprzątać – Sebas

+0

Co "z filtru wchodzi funkcjonalnie w warunek JOIN" lub "[filtr] jest faktycznym warunkiem łączenia, a nie tylko filtrem"? W każdym razie pojęcie "tylko filtr" nie jest pomocne, ponieważ znaczenie 'JOIN NA c AND d' jest takie samo jak' JOIN ON c WHERE d'. (W rzeczywistości standard SQL * definiuje * JOIN ON w odniesieniu do JOIN WHERE.) Podobnie "implicitely anuluje naturę OUTERA" * po prostu nie komunikuje niczego *. Z czym wydaje się pan zgadzać, skoro opatrujesz go adnotacją, w której cytowany jest strach (stąd samo jest niejasny) "(" dołącz nawet wtedy, gdy nie ma zapisów ")". Nie wyjaśniasz. – philipxy

5

JOIN Warunki powinny być zwykle niezależne od warunków filtrowania. Możesz zdefiniować reguły swojego łączenia (jak) z ON. Filtrujesz , co chcesz, z . Wydajność, nie ma ogólnej zasady we wszystkich silnikach i projektach, więc Twój przebieg będzie bardzo różny.

0

Myślę, że szybszym sposobem jest umieszczenie filtru w klauzuli where, ponieważ będzie on przetwarzał ten filtr w pierwszym miejscu, a następnie w klauzulę złączenia, więc nie będzie potrzeby stosowania permutacji filtrów.

+0

Nie ma żadnej różnicy dla DBMS z jakąkolwiek optymalizacją. Np. Zobacz dokumentację MySQL na temat optymalizacji SELECT/JOIN: WŁĄCZONE JEDNOSTKI WEWNĘTRZNE są traktowane tak, jakby to było WHERE zastosowane do tego JOIN. – philipxy

Powiązane problemy