W Learn SQL the Hard Way (ćwiczenie szóste) autor przedstawia następujące zapytanie:
SELECT pet.id, pet.name, pet.age, pet.dead
FROM pet, person_pet, person
WHERE
pet.id = person_pet.pet_id AND
person_pet.person_id = person.id AND
person.first_name = "Zed";
a następnie mówi, że:
Istnieją inne sposoby na uruchomienie tego rodzaju zapytań, zwane „złączeniami”. Na razie unikam tych koncepcji, ponieważ są niesamowicie mylące. Po prostu trzymaj się tego sposobu łączenia na razie i ignoruj ludzi, którzy próbują powiedzieć ci, że jest to jakoś wolniejsze lub „niskiej klasy”.
Czy to prawda? Dlaczego lub dlaczego nie?
Odpowiedzi:
Dzięki podejściu autora nauczanie POŁĄCZEŃ ZEWNĘTRZNYCH stanie się znacznie trudniejsze. Klauzula ON w INNER JOIN nigdy nie była dla mnie oszałamiająca jak wiele innych rzeczy. Może dlatego, że nigdy nie nauczyłem się starego sposobu. Chciałbym pomyśleć, że istnieje powód, dla którego się go pozbyliśmy i że nie było to zadowolone z siebie i nazwać tę metodę niską klasą.
To prawda w bardzo wąskim scenariuszu, który autor stworzył:
Myślę, że w ramach postępu nauczania łatwiej jest go rozbić i osiągnąć naturalny postęp:
Pojęcia łączenia i filtrowania tabel nie są tak naprawdę takie same. Nauka prawidłowej składni będzie miała teraz więcej przeniesień, gdy nauczysz się ŁĄCZNIKÓW ZEWNĘTRZNYCH, chyba że autor zamierza uczyć przestarzałych / przestarzałych rzeczy, takich jak:
*= or =*
.źródło
*=
lub=*
wskazuje lewe lub prawe sprzężenia zewnętrzne, inne użyłem tylko obsługiwane lewe połączenia zewnętrzne za pomocą|=
operatora.+=
a może tak było=+
. Wierzę, że*=
był Transact-SQL (Sybase i później MS-SQL). Wciąż dobra uwaga.WHERE
klauzuli. (Słyszałem, że jest to połączenie theta , ale nie jestem pewien, czy to prawda).To, czy będzie wolniejsze, zależy od Optymalizatora zapytań i od tego, jak usprawnia ono zapytanie (to, co piszesz, nie jest tak naprawdę wykonywane). Jednak dużym problemem związanym z tym cytatem jest to, że całkowicie ignoruje on fakt, że istnieją różne rodzaje złączeń, które działają zupełnie inaczej. Na przykład to, co się mówi, jest (teoretycznie) prawdziwe
inner joins
, ale nie jest prawdziwe dlaouter joins
(left joins
iright joins
).źródło
INNER JOIN
alboLEFT OUTER JOIN
. Nie są „szalenie mylące”. SQL może być niesamowicie mylący, ale to nie jest tego przykład.Autor przedstawia prosty przypadek, w którym można zastosować starą lub nową składnię. Nie zgadzam się z jego stwierdzeniem, że złączenia są niesamowicie mylące, ponieważ łączenie tabel jest podstawową koncepcją zapytań SQL. Być może więc autor powinien poświęcić trochę czasu na wyjaśnienie, jak działa JOINS przed wypowiedzeniem wyrażonego zdania, a także na przykładzie zapytania z wieloma tabelami.
Należy użyć nowszej składni. Głównym argumentem jest to, że twoje zapytanie będzie miało:
Przy użyciu starego stylu łączone są kryteria łączenia i filtrowania, co w bardziej skomplikowanych przypadkach może prowadzić do zamieszania.
Można również uzyskać produkt kartezjański, zapominając o kryteriach łączenia w klauzuli filtrującej:
używając starszej składni.
Użycie nowszej składni określa również sposób łączenia, co jest ważne, czy chcesz INNER, LEFT OUTER itp., Więc jest bardziej wyraźne w odniesieniu do składni JOIN, która IMHO zwiększa czytelność dla osób, które nie znają łączenia tabel.
źródło
Nie powinno być, parser zapytań powinien generować równoważną wewnętrzną reprezentację dla równoważnych zapytań, niezależnie od tego, jak zostały napisane. Autor po prostu używa składni sprzed SQL-92, dlatego wspomina, że może to być postrzegane jako „staromodne” lub „niskiej klasy”. Analizator składni i optymalizator powinny wewnętrznie wygenerować ten sam plan zapytań.
źródło
W ten sposób nauczyłem się SQL, w tym
*=
składni sprzężeń zewnętrznych. Dla mnie było to bardzo intuicyjne, ponieważ wszystkie relacje miały równy priorytet i lepiej zadawały pytania w postaci szeregu pytań: Czego chcesz? Skąd chcesz? Który chcesz?Wykonując
join
składnię, silniej zaburza proces myślenia o relacjach. Osobiście uważam, że kod jest znacznie mniej czytelny, a tabele i relacje są ze sobą powiązane.Przynajmniej w MSSQL nie ma znaczącej różnicy w wydajności zapytań, przy założeniu, że używasz tej samej kolejności łączenia. To powiedziawszy, istnieje jeden wyraźny, ogromny problem z uczeniem się (i używaniem) SQL w ten sposób. Jeśli zapomnisz o jednym ze swoich relacji, otrzymasz nieoczekiwane efekty krzyżowe. Które w bazie danych o dowolnym nietrywialnym rozmiarze są wyjątkowo drogie (i niebezpieczne dla osób, które nie wybierają!). Znacznie trudniej jest zapomnieć o relacji podczas korzystania ze
join
składni stylu.źródło
Należy wziąć pod uwagę dwa różne aspekty: wydajność i łatwość konserwacji / czytelność .
Konserwowalność / czytelność
Wybrałem inne zapytanie, ponieważ uważam, że jest to lepszy / gorszy przykład niż pierwotne zapytanie, które opublikowałeś.
Co dla ciebie wygląda lepiej i jest bardziej czytelne?
Lub...
Dla mnie osobiście pierwszy jest dość czytelny. Widzisz, że łączymy tabele
INNER JOIN
, co oznacza, że ściągamy wiersze, które pasują do kolejnej klauzuli łączenia (tj. „Dołącz Pracownik do EmployeeDepartmentHistory na BusinessEntityID i dołącz te wiersze”).Ten ostatni przecinek nic dla mnie nie znaczy. Zastanawiam się, co robisz z tymi wszystkimi
WHERE
predykatami klauzul.Ten pierwszy czyta więcej, jak myśli mój mózg. Patrzę na SQL przez cały dzień i przecinki dla złączeń. Co prowadzi mnie do następnego punktu ...
Wszystkie są złączeniami. Nawet przecinki są złączeniem. Fakt, że autor ich nie nazywa, jest rzeczywiście ich upadkiem ... nie jest oczywiste. To powinno być oczywiste. Dołączasz do danych relacyjnych, niezależnie od tego, czy określisz,
JOIN
czy,
.Wydajność
Z pewnością będzie to zależne od RDBMS. Mogę mówić tylko w imieniu Microsoft SQL Server. Pod względem wydajności są one równoważne. Skąd wiesz? Uchwyć plany po wykonaniu i zobacz, co dokładnie robi SQL Server dla każdej z tych instrukcji:
Na powyższym obrazku podkreśliłem, że używam obu zapytań jak powyżej, różniących się tylko wyraźnymi znakami dla złączenia (
JOIN
vs,
). SQL Server robi dokładnie to samo.Podsumowanie
Nie używaj przecinków. Używaj wyraźnych
JOIN
instrukcji.źródło
Nie, to wcale nie jest prawda. Autor ustawia czytelników na zamieszanie i zachęca do programowania kultowego, które pozwala uniknąć bardzo dużej różnicy strukturalnej między standardową składnią a tym starszym wariantem, który preferuje. W szczególności zaśmiecona klauzula WHERE utrudnia ustalenie, co sprawia, że jego zapytanie jest wyjątkowe.
Jego przykład prowadzi czytelnika do wygenerowania mentalnej mapy jego znaczenia, która ma strasznie dużo bałaganu.
Z grubsza powyższe jest:
Przy takiej mapie mentalnej czytelnik (z jakiegoś powodu ręcznie piszący SQL) może bardzo łatwo popełnić błąd, prawdopodobnie pomijając jedną lub więcej tabel. A czytnik tak napisanego kodu będzie musiał pracować ciężej, aby dowiedzieć się dokładnie, co autor SQL próbuje zrobić. („Trudniejsze” jest na poziomie czytania SQL z podświetlaniem składni lub bez, ale wciąż jest to różnica większa niż zero).
Jest powód, dla którego JOIN są powszechne, i to jest stara, klasyczna „canard seperation of koncern”. W szczególności w przypadku zapytania SQL istnieje dobry powód, aby rozdzielić strukturę danych i sposób ich filtrowania.
Jeśli zapytanie jest napisane czystsze, takie jak
Następnie czytelnik ma wyraźniejsze rozróżnienie między składnikami tego, o co jest proszony. Filtr wyróżniający tego zapytania jest oddzielony od tego, w jaki sposób jego komponenty odnoszą się do siebie, a niezbędne komponenty każdej relacji znajdują się bezpośrednio tam, gdzie są wymagane.
Oczywiście żaden nowoczesny system bazy danych nie powinien widzieć znaczącej różnicy między tymi dwoma stylami. Ale jeśli wydajność bazy danych byłaby jedyną kwestią, zapytanie SQL nie zawierałoby białych znaków ani wielkich liter.
źródło
Facet popełnia klasyczny błąd. Próbuje uczyć abstrakcyjnej koncepcji z konkretną implementacją. Jak tylko to zrobisz, wpadniesz w taki bałagan.
Powinien był najpierw nauczyć podstawowych pojęć dotyczących bazy danych, a następnie pokazać SQL jako jeden ze sposobów ich opisu.
Połączenia lewy i prawy, można argumentować, że nie mają one większego znaczenia. Outer Join, możesz użyć starej
*=
i=*
składni.Teraz możesz argumentować, że składnia jest prostsza, ale tylko dla prostych zapytań. Gdy tylko zaczniesz próbować wykonać złożone zapytanie w tej wersji, możesz wpaść w straszny bałagan. „Nowa” składnia nie została wprowadzona, aby można było wykonywać złożone zapytania, było to więc wykonywanie złożonych zapytań w sposób czytelny, a zatem możliwy do utrzymania.
źródło
Przykład jest równoznaczny z prostym przeformułowaniem z wewnętrznymi JOIN. Różnica polega wyłącznie na dodatkowych możliwościach, na które pozwala składnia JOIN. Na przykład możesz określić kolejność przetwarzania kolumn dwóch tabel; patrz np . https://stackoverflow.com/a/1018825/259310 .
Otrzymaną mądrością jest, w razie wątpliwości, pisanie zapytań w sposób, który czyni je bardziej czytelnymi. Ale to, czy łatwiej jest czytać POŁĄCZENIA lub GDZIE, wydaje się być kwestią osobistych preferencji i dlatego obie formy są tak rozpowszechnione.
źródło
WHERE
klauzuli, czy umieścisz wJOIN
instrukcji, może faktycznie wpłynąć na wydajność w zależności od Optymalizatora zapytań. Widziałem to więcej niż jeden raz.Kiedy nauczyłem się SQL, formularze INNER JOIN, LEFT JOIN itp. Nie istniały. Jak już stwierdzono w innych odpowiedziach, różne dialekty SQL miały zaimplementowane sprzężenia zewnętrzne przy użyciu składni idiosynkratycznej. To uszkodziło przenośność kodu SQL. Ponowne połączenie języka wymagało pewnej zmiany, a LEWE DOŁĄCZENIE itp. Było tym, na czym się zdecydowali.
Prawdą jest, że dla każdego DOŁĄCZENIA WEWNĘTRZNEGO można zapisać równoważne połączenie przecinkiem z warunkiem złączenia w klauzuli WHERE. Przejście od polubienia starej formy do preferowania nowej zajęło mi trochę czasu. Najwyraźniej autor Learning SQL the Hard Way nadal uważa, że stary sposób jest łatwiejszy.
Czy są jakieś różnice? Cóż, tak, są. Po pierwsze, INNER JOIN z klauzulą ON ujawnia intencje autora wyraźniej niż połączenie starego stylu. Fakt, że klauzula ON jest w rzeczywistości warunkiem łączenia, a nie jakimkolwiek innym ograniczeniem, jest bardziej oczywisty. To sprawia, że kod korzystający z INNER JOIN jest łatwiejszy do nauczenia się podczas czytania niż stary styl. Jest to ważne przy utrzymywaniu kodu innej osoby.
Druga różnica polega na tym, że nowy styl nieznacznie ułatwia optymalizatorowi zapytań znalezienie zwycięskiej strategii. To bardzo mały efekt, ale jest prawdziwy.
Trzecia różnica polega na tym, że kiedy nauczysz się używać INNER JOIN (lub zwykłego JOIN), łatwiej jest nauczyć się LEFT JOIN itp.
Poza tym nie ma żadnej istotnej różnicy.
źródło
To zależy, czy myślisz w kategoriach zbiorów i logiki formalnej .....
Jeśli tego nie zrobisz, nieużywanie słowa kluczowego „Join” ułatwia przejście z logiki formalnej do SQL.
Ale jeśli jak 99% ludzi, nie cieszyłeś się logiką formalną z matematyki, to słowo kluczowe Join jest łatwiejsze do nauczenia się. SQL był prezentowany na uniwersytecie jako inny sposób zapisywania formalnych zapytań logicznych ...
źródło