2010-02-24 21 views
7

Nie mogę się zdecydować, aby użyć JOIN, gdy mogę łatwo rozwiązać ten sam problem, używając wewnętrznego zapytania:Dlaczego używać JOIN zamiast wewnętrznych zapytań

np.

SELECT COLUMN1, (SELECT COLUMN1 FROM TABLE2 WHERE TABLE2.ID = TABLE1.TABLE2ID) AS COLUMN2 FROM TABLE1;

Moje pytanie brzmi, czy to jest złą praktyką programowania? Uważam, że łatwiej jest czytać i utrzymywać w przeciwieństwie do łączenia.

UPDATE

Chcę dodać, że istnieje jakiś wielki tu sprzężenie zwrotne, które w istocie pcha z powrotem do używania JOIN. Obecnie coraz mniej angażuję się w używanie TSQL bezpośrednio w wyniku rozwiązań ORM (LINQ do SQL, NHibernate itp.), Ale kiedy to robię, takie rzeczy jak skorelowane podzapytania, które znajduję, są łatwiejsze do wypisania liniowo .

+7

Z powodu wydajności i łatwości konserwacji. Gdy już przyzwyczaisz się do 'join's, nigdy nie wrócisz. – voyager

+3

-1: Poważnie? Zalety składni JOIN nie są oczywiste? –

+5

Tej nocy dowiedziałem się, że wewnętrzne zapytanie dodało 1,7 sekundy do 0,002 sekundy zapytania. – Nicole

Odpowiedz

8

Osobiście uważam, że jest to niezwykle trudne do odczytania. Nie jest to struktura oczekiwana przez programistę SQL. Używając JOIN, przechowujesz wszystkie źródła tabel w jednym miejscu zamiast rozprzestrzeniać je w zapytaniu.

Co się stanie, jeśli potrzebujesz trzech lub czterech połączeń? Umieszczenie tych wszystkich w klauzuli SELECT stanie się owłosione.

+0

"Plan wyjaśniający będzie taki sam pomiędzy tymi dwoma podejściami." - W tym przykładzie może to być prawdą (może nawet dla wszystkich wersji SQL Server), ale gdy tylko zapytanie wewnętrzne staje się bardziej złożone, często już tak nie jest. Zamiast tego serwer przetwarza jeden wiersz po drugim zamiast pełnego zestawu, który jest niesamowicie wolny w przypadku dużych zestawów danych. – Lucero

+0

@ Lucero - Dobra uwaga. Zmodyfikowałem moją odpowiedź. –

6

Łączenie jest zwykle szybsze niż skorelowane podzapytanie, ponieważ działa na zestawie wierszy, a nie na jednym wierszu naraz. Nigdy nie pozwoliłbym, aby ten kod trafił na mój serwer produkcyjny.

Uważam, że łączenie jest o wiele łatwiejsze do odczytania i utrzymywania.

6

Jeśli potrzebna jest więcej niż jedna kolumna z drugiej tabeli, wówczas wymagane są dwa podzapytania. Zwykle nie będzie to działać tak dobrze jak sprzężenie.

1

To nie jest zła praktyka programistyczna na wszystkich IMO, jest jednak trochę brzydka. W rzeczywistości może to być zwiększenie wydajności w sytuacjach, w których sub-selekcja pochodzi z bardzo dużej tabeli, podczas gdy oczekuje się bardzo małego zestawu wyników (należy wziąć pod uwagę indeksy i platformę, 2000 z innym optymalizatorem i wszystkie z 2005). Oto, jak go sformatować, aby był łatwiejszy do odczytania.

select 
    column1 
    [column2] = (subselect...) 
from 
    table1 

Edit: To oczywiście zakłada, że ​​SUBSELECT zwróci jedynie jedną wartość, jeśli nie może to być powrót wam złe wyniki. Zobacz odpowiedź gbn.

0

to sprawia, że ​​o wiele łatwiej wykorzystywać inne rodzaje złączeń (lewy skrajny, krzyża, etc), ponieważ składnia dla tych, pod względem podzapytanie jest mniej niż idealne dla czytelności

4

To nie jest równoznaczne z JOIN.

Jeśli masz wiele wierszy w TABELI2 dla każdego wiersza w TABELI1, nie otrzymasz ich. Dla każdego wiersza w TABELIE 1 otrzymujesz jedno wyjście wiersza, więc nie można uzyskać wielu z TABELA2.

To dlatego użyję „DOŁĄCZ”: aby upewnić się uzyskać dane chciałam ...

Po aktualizacji: ja rzadko korzystają korelację z wyjątkiem istnieje ...

4

Zapytanie używasz często stosowany jako zamiennik dla LEFT JOIN dla silników, które brakowało (zwłaszcza, PostgreSQL przed 7.2)

Takie podejście ma pewne poważne wady:

  1. It może się nie powieść, jeśli nie jest UNIQUE

  2. Niektóre silniki nie będą mogły używać do tego celu wartości innej niż uery

  3. Jeśli chcesz wybrać więcej niż jedną kolumnę, trzeba będzie napisać Podzapytanie kilkakrotnie

Jeśli silnik obsługuje LEFT JOIN użyj LEFT JOIN.

Jednak w niektórych przypadkach w MySQL funkcja agregująca w podzapytaniu na poziomie wyboru może być bardziej wydajna niż w przypadku LEFT JOIN z GROUP BY.

Zobacz artykuł w moim blogu na przykładach:

0

Pod koniec dnia, celem przy pisaniu kodu, poza wymaganiami funkcjonalnymi, jest uczynienie intencji Twój kod jest czytelny dla czytelnika. Jeśli używasz JOIN, intencja jest oczywista. Jeśli używasz podkwerendy w sposób, który opisujesz, to nasuwa się pytanie, dlaczego zrobiłeś to w ten sposób. Czego próbujesz osiągnąć, aby DOŁĄCZ nie zakończyło się sukcesem? Mówiąc krótko, marnujesz czas czytelnika, próbując ustalić, czy autor rozwiązał jakiś problem w genialny sposób, czy też napisał kod po ciężkiej nocy picia.

Powiązane problemy