Dlaczego standard SQL ANSI-92 nie jest lepiej przyjęty niż ANSI-89?

107

W każdej firmie, w której pracowałem, zauważyłem, że ludzie nadal piszą swoje zapytania SQL w standardzie ANSI-89:

select a.id, b.id, b.address_1
from person a, address b
where a.id = b.id

zamiast standardu ANSI-92:

select a.id, b.id, b.address_1
from person a
inner join address b
on a.id = b.id

W przypadku niezwykle prostego zapytania, takiego jak to, nie ma dużej różnicy w czytelności, ale w przypadku dużych zapytań okazuje się, że pogrupowanie kryteriów łączenia z listą tabeli znacznie ułatwia sprawdzenie, gdzie mogą wystąpić problemy z połączeniem, i pozwól mi zachować całe moje filtrowanie w mojej klauzuli WHERE. Nie wspominając już o tym, że czuję, że łączenia zewnętrzne są dużo intuicyjne niż składnia (+) w Oracle.

Kiedy próbuję ewangelizować ANSI-92 wśród ludzi, czy są jakieś konkretne korzyści z używania ANSI-92 w porównaniu z ANSI-89? Chciałbym wypróbować to sam, ale konfiguracje Oracle, które tutaj mamy, nie pozwalają nam na użycie EXPLAIN PLAN - czy nie chciałbyś, aby ludzie próbowali zoptymalizować swój kod, prawda?

Patrick Harrington
źródło
7
Jedną z głównych zalet notacji złączeń SQL-92 jest to, że istnieje standardowy i względnie rozsądny sposób zapisu LEFT OUTER JOIN i wariantów. Każdy DBMS miał swój własny wariant składni (zwykle zły; właściwie myślę, że bez wyjątku notacje były złe) i często z nieco inną semantyką. SQL-92 to naprawił i nowy zapis jest wart używania tylko na tych podstawach. Myślę, że i tak jest to wyraźniejsze, kiedy już się do tego przyzwyczaisz. Trochę trzeba się do tego przyzwyczaić, ale nie jest to trudne, a po nawróceniu nie ma powrotu.
Jonathan Leffler
semantyka, shemantics, anti-shemantics!
Sam
Trochę spóźniłem się na imprezę tutaj, ale wydaje się, że nikt nie zauważył, że same Oracle zaleca użycie składni FROM klauzuli OUTER JOIN zamiast operatora dołączania Oracle
bornfromanegg
Dodałem nową odpowiedź, która jest o wiele bardziej aktualna i prosta, z jasnością nad innymi nieporozumieniami w odpowiedziach tutaj stackoverflow.com/a/47720615/124486
Evan Carroll

Odpowiedzi:

77

Według raportu „SQL Performance Tuning” Petera Gulutzana i Trudy Pelzer, z sześciu lub ośmiu testowanych przez nich marek RDBMS, nie było różnicy w optymalizacji lub wydajności łączenia SQL-89 i SQL-92. Można założyć, że większość silników RDBMS przekształca składnię w wewnętrzną reprezentację przed optymalizacją lub wykonaniem zapytania, więc składnia czytelna dla człowieka nie robi różnicy.

Próbuję też ewangelizować składnię SQL-92. Szesnaście lat po zatwierdzeniu, najwyższy czas, aby ludzie zaczęli go używać! Wszystkie bazy danych SQL obsługują ją teraz, więc nie ma powodu, aby nadal używać niestandardowej (+)składni Oracle lub składni *=Microsoft / Sybase.

Jeśli chodzi o to, dlaczego tak trudno jest zerwać społeczność programistów z nawykiem SQL-89, mogę tylko założyć, że istnieje duża „baza piramidy” programistów, którzy kodują metodą kopiowania i wklejania, używając starożytnych przykładów z książek, artykułów z czasopism, lub inna baza kodu, a ci ludzie nie uczą się nowej składni w sposób abstrakcyjny. Niektórzy ludzie dopasowują się do wzorców, a niektórzy uczą się na pamięć.

Jednak stopniowo widzę ludzi używających składni SQL-92 częściej niż kiedyś. Odpowiadam na pytania SQL online od 1994 roku.

Bill Karwin
źródło
6
W pełni się zgadzam. Pracuję z wieloma programistami SQL, którzy nauczyli się języka SQL 15 lat temu lub więcej (tak jak ja sam) i którzy nie wiedzą nic o żadnych innowacjach, odkąd zaczęli. Nie są też zainteresowani dowiedzeniem się.
Tony Andrews
8
Zgadzam się, ale dodajmy, że istnieją dobrze udokumentowane scenariusze, w których stara składnia łączenia ANSI-89 daje niepoprawne wyniki ... w szczególności łączenia zewnętrzne, gdy istnieją predykaty filtrowania warunkowego dla kolumn niezwiązanych z łączeniem z „zewnętrznej” strony sprzężenia.
Charles Bretana
1
Nie znam konkretnych wewnętrznych cech MS SQL, ale to dobry anegdotyczny dowód na to, że składnia SQL-92 jest warta zachodu. Pracuje dla mnie!
Bill Karwin,
2
Masywny? Opublikuj swoją pracę. My najlepiej jest, że to nie jest do porównania jabłka jabłka, ale nie reagują z „oh tak to jest” Wystarczy odpowiedzieć przypadku testowego możemy rozmnażać, wersja, łaty itd.
2
Poza tym „anegdotyczne” dowody i tak nie są miarą naukową. Zawsze przyjmuje się go z przymrużeniem oka.
Bill Karwin
16

Cóż, standard ANSI092 zawiera dość ohydną składnię. Połączenia naturalne to jedno, a klauzula USING to drugie. IMHO, dodanie kolumny do tabeli nie powinno zepsuć kodu, ale NATURALNE JOIN zepsuje się w najbardziej rażący sposób. „Najlepszym” sposobem na przerwanie jest błąd kompilacji. Na przykład, jeśli gdzieś wybierzesz *, dodanie kolumny możenie udało się skompilować. Następnym najlepszym sposobem na niepowodzenie byłby błąd czasu wykonywania. Jest gorzej, ponieważ Twoi użytkownicy mogą to zobaczyć, ale nadal daje ładne ostrzeżenie, że coś zepsułeś. Jeśli używasz ANSI92 i piszesz zapytania z łączeniami NATURAL, nie ulegnie on awarii w czasie kompilacji i nie ulegnie awarii w czasie wykonywania, zapytanie nagle zacznie dawać błędne wyniki. Tego typu błędy są podstępne. Raporty są błędne, potencjalne informacje finansowe są nieprawidłowe.

Dla tych, którzy nie są zaznajomieni z połączeniami NATURAL. Łączą dwie tabele w każdej nazwie kolumny, która istnieje w obu tabelach. Co jest naprawdę fajne, gdy masz 4-kolumnowy klucz i masz dość wpisywania go. Problem pojawia się, gdy Tabela1 ma wcześniej istniejącą kolumnę o nazwie DESCRIPTION i dodajesz nową kolumnę o nazwie Table2 o nazwie, och, nie wiem, coś nieszkodliwego, jak mmm, DESCRIPTION, a teraz dołączasz do dwóch tabel na VARCHAR2 (1000) pole o dowolnym kształcie.

Klauzula USING może prowadzić do całkowitej niejednoznaczności oprócz problemu opisanego powyżej. W innym poście SO ktoś pokazał ten ANSI-92 SQL i poprosił o pomoc w jego czytaniu.

SELECT c.* 
FROM companies AS c 
JOIN users AS u USING(companyid) 
JOIN jobs AS j USING(userid) 
JOIN useraccounts AS us USING(userid) 
WHERE j.jobid = 123

To jest całkowicie niejednoznaczne. Umieściłem kolumnę UserID w tabelach firm i użytkowników i nie ma żadnych skarg. Co się stanie, jeśli kolumna ID użytkownika w firmach jest identyfikatorem ostatniej osoby, która zmodyfikowała ten wiersz?

Mówię poważnie, czy ktoś może wyjaśnić, dlaczego taka dwuznaczność była konieczna? Dlaczego jest wbudowany bezpośrednio w standard?

Myślę, że Bill ma rację, że istnieje duża baza programistów, którzy kopiują / wklejają tam przez kodowanie. Prawdę mówiąc, mogę przyznać, że jestem taki, jeśli chodzi o ANSI-92. Każdy przykład, jaki kiedykolwiek widziałem, pokazywał, że wiele złączeń jest zagnieżdżonych w nawiasach. Szczerość, która sprawia, że ​​wybieranie stolików w sql jest w najlepszym razie trudne. Ale potem ewangilista SQL92 wyjaśnił, że faktycznie wymusiłoby to kolejność łączenia. JEZUS ... wszyscy ci kopiący pasterze, których widziałem, wymuszają teraz polecenie łączenia - zadanie, które w 95% przypadków lepiej pozostawić optymalizatorom, zwłaszcza kopiowaniu / pasterowi.

Tomalak dobrze zrozumiał, kiedy powiedział:

ludzie nie przechodzą na nową składnię tylko dlatego, że ona istnieje

To musi mi coś dać i nie widzę korzyści. A jeśli jest plus, negatywy to albatros zbyt duży, aby je zignorować.

Społeczność
źródło
3
Zwykle używam ON, ponieważ jest mniej niejednoznaczne niż USING lub NATURAL JOIN. Jeśli chodzi o nawiasy, osoby, które uczą się języka „SQL” w programie Microsoft Access, będą go używać, gdy program Access narzeknie, jeśli je pominiesz. (Cudzysłowy wokół SQL powinny być cudzysłowami)
Powerlord,
1
Kaszel Co to jest klauzula USING? ;-) Pochodzę z frakcji SQL Server, więc nie mam tego na radarze. Jak powiedział R. Bemrose, istnieje klauzula ON, działająca dobrze, nigdy nie pozostawiająca mnie z łączeniem, którego nie potrafiłbym wyrazić syntaktycznie. Nie ma potrzeby dostosowywania projektu bazy danych do składni zapytań, aby zaoszczędzić trochę pisania.
Tomalak
3
Jeśli nie znasz swoich danych na tyle dobrze, aby użyć NATURAL JOIN lub USING, gdy jest to stosowne, prawdopodobnie nie powinieneś pisać dla nich SQL. -1 za ignorancję.
Rob
4
IMHO, naturalne łączenia wpadają do tego samego worka co SELECT *(wtedy dowiadujemy się, że klient polega na zamówieniu w terenie) - Po prostu wydaje się trochę niechlujny
Podstawowy
2
Problem, który opisujesz z naturalnymi złączeniami, to problem z projektem bazy danych - a nie ze standardem. powinieneś być świadomy swoich danych i ustanowić standardy nazw kolumn.
Travis,
14

Przychodzi mi na myśl kilka powodów:

  • ludzie robią to z przyzwyczajenia
  • ludzie są leniwi i wolą łączenia w „starym stylu”, ponieważ wymagają mniej pisania
  • początkujący często mają problemy z zawijaniem głowy wokół składni łączenia SQL-92
  • ludzie nie przechodzą na nową składnię tylko dlatego, że ona istnieje
  • ludzie nie są świadomi korzyści płynących z nowej (jeśli chcesz to tak nazwać) składni, przede wszystkim tego, że umożliwia ona filtrowanie tabeli przed wykonaniem sprzężenia zewnętrznego, a nie po nim, gdy wszystko, co masz, to klauzula WHERE.

Ze swojej strony wykonuję wszystkie sprzężenia w składni SQL-92 i konwertuję kod tam, gdzie mogę. Jest to czystszy, bardziej czytelny i skuteczniejszy sposób. Ale trudno jest przekonać kogoś do używania nowego stylu, gdy uważa, że ​​boli go to, ponieważ wymaga więcej pracy na klawiaturze bez zmiany wyniku zapytania.

Tomalak
źródło
3
Wielu osobom patrzenie na SQL w ogóle szkodzi. Zmiana dowolnego działającego kodu niesie ze sobą ryzyko wprowadzenia błędu, zwłaszcza gdy programista odwraca wzrok. :-)
Bill Karwin
Hm ... dla mnie nawet patrzenie na złożone wyrażenia regularne nie jest bolesne. SQL nie może mi zaszkodzić. ;-)
Tomalak
„Początkujący często mają problemy ...” Cóż, TO jest punkt sprzedaży
2
Z jakiegoś powodu nie jestem pewien, czy to był komentarz „za” czy „przeciw” ... Może mój detektor ironii jest uszkodzony.
Tomalak
10

W odpowiedzi na powyższy post NATURAL JOIN and USING.

DLACZEGO kiedykolwiek widziałbyś potrzebę ich użycia - nie były one dostępne w ANSI-89 i zostały dodane dla ANSI-92 jako coś, co widzę tylko jako skrót.

Nigdy nie zostawiłbym połączenia przypadkowi i zawsze określałbym tabelę / alias i identyfikator.

Dla mnie jedyną możliwą drogą jest ANSI-92. Jest bardziej rozwlekły, a składnia nie jest lubiana przez zwolenników ANSI-89, ale zgrabnie oddziela SPRZĘŻENIA od FILTROWANIA.

Roger Bold
źródło
Nie widzę NATURAL JOIN jako skrótu, ale Segway do programowania obiektowego DB w relacyjnej bazie danych.
Armand,
5

Najpierw powiem, że w SQL Server składnia sprzężenia zewnętrznego (* =) nie daje przez cały czas poprawnych wyników. Są chwile, kiedy interpretuje to jako połączenie krzyżowe, a nie połączenie zewnętrzne. Jest więc dobry powód, aby przestać go używać. A ta składnia sprzężenia zewnętrznego jest przestarzałą funkcją i nie będzie dostępna w następnej wersji SQL Server po SQL Server 2008. Nadal będziesz w stanie wykonywać sprzężenia wewnętrzne, ale dlaczego ktoś miałby to robić? Są niejasne i dużo trudniejsze w utrzymaniu. Nie łatwo wiesz, co jest częścią złączenia, a co tak naprawdę jest tylko klauzulą ​​Where.

Jednym z powodów, dla których uważam, że nie powinieneś używać starej składni, jest to, że zrozumienie łączy i tego, co robią, a czego nie, jest krytycznym krokiem dla każdego, kto napisze kod SQL. Nie powinieneś pisać żadnego kodu SQL bez dokładnego zrozumienia złączeń. Jeśli dobrze je zrozumiesz, prawdopodobnie dojdziesz do wniosku, że składnia ANSI-92 jest jaśniejsza i łatwiejsza w utrzymaniu. Nigdy nie spotkałem eksperta od SQL, który nie używałby składni ANSI-92 zamiast starej składni.

Większość ludzi, z którymi się spotkałem lub z którymi miałem do czynienia, którzy używają starego kodu, naprawdę nie rozumie złączeń i przez to wpada w kłopoty podczas wysyłania zapytań do bazy danych. To jest moje osobiste doświadczenie, więc nie mówię, że zawsze jest prawdą. Ale jako specjalista od danych musiałem przez lata naprawiać zbyt wiele tych śmieci, żeby w to nie wierzyć.

HLGEM
źródło
1
Miło cię poznać. Cieszę się, że jestem pierwszym.
4

W szkole uczyłem się ANSI-89 i przez kilka lat pracowałem w przemyśle. Potem na 8 lat opuściłem bajkowy świat DBMS. Ale potem wróciłem i nauczono tego nowego materiału ANSI 92. Nauczyłem się składni Join On, a teraz faktycznie uczę SQL i polecam nową składnię JOIN ON.

Ale wadą, którą widzę, są skorelowane podzapytania, które nie mają sensu w świetle złączeń ANSI 92. Kiedy informacje o złączeniach zostały uwzględnione w GDZIE, a skorelowane podzapytania są „połączone” w GDZIE, wszystko wydawało się prawidłowe i spójne. W ANSI 92 kryteria łączenia tabel nie znajdują się w GDZIE, a podzapytanie „łączenie” jest, składnia wydaje się niespójna. Z drugiej strony próba „naprawienia” tej niespójności prawdopodobnie tylko pogorszy sytuację.

Scot McDermid
źródło
Z drugiej strony, p [robaly nie powinien w ogóle pisać skorelowanych podzapytań, ponieważ są to wieprze wydajności. Są jak umieszczanie kursora w zapytaniu. Fuj.
HLGEM,
3

Nie znam odpowiedzi na pewno ... to jest wojna religijna (prawie w mniejszym stopniu niż Mac-PC lub inne)

Można przypuszczać, że do niedawna Oracle (i być może także inni dostawcy) nie przyjęli standardu ANSI-92 (myślę, że był to Oracle v9, lub coś podobnego), a więc w przypadku DBA / Db Developers pracujących w firmach, które nadal używali tych wersji (lub chcieli, aby kod był przenośny między serwerami, które mogą używać tych wersji, musieli trzymać się starego standardu ...

Naprawdę szkoda, ponieważ nowa składnia złączeń jest znacznie bardziej czytelna, a stara składnia generuje błędne (niepoprawne) wyniki w kilku dobrze udokumentowanych scenariuszach.

  • W szczególności łączenie zewnętrzne, gdy istnieją predykaty filtrowania warunkowego w kolumnach niezwiązanych ze sprzężeniem z tabeli po „zewnętrznej” stronie sprzężenia.
Charles Bretana
źródło
Tak, Oracle 9i; wydany w 2001 roku. Trochę za późno na imprezę!
1
MS SQL dodano INNER JOINw 1995 r., Ale LEFT JOINdopiero w 1996 r. MySQL obsługuje go co najmniej od wersji 3.23, wydanej w 1999 r .; PostgreSQL przynajmniej od wersji 7.2, wydanej w 2002 roku. Niektóre zwykłe Googlowanie nie daje mi odpowiedzi na temat Teradata.
Tak, to było potępienie, które udowodniło wyższość Oracle w 1991 roku: systemy bazodanowe, takie jak dostęp do MS, które używają składni „lewej” i „prawej”, nie były standardowym SQL ANSI. Publikowanie takiego kodu SQL było dla innych okazją do wyśmiewania się z Ciebie. Teraz trochę jak Twitter i Facebook.
david
2

Bezwładność i praktyczność.

ANSI-92 SQL przypomina pisanie bezwzrokowe. W pewnym sensie teoretycznie może to kiedyś poprawić wszystko, ale teraz mogę pisać znacznie szybciej, patrząc na klawisze czterema palcami. Musiałbym cofnąć się, aby iść naprzód, bez gwarancji, że kiedykolwiek nastąpi zwrot.

Pisanie SQL to około 10% mojej pracy. Jeśli potrzebuję ANSI-92 SQL do rozwiązania problemu, którego ANSI-89 SQL nie może rozwiązać, użyję go. (Właściwie używam go w Accessie). Gdyby używanie go cały czas pomogło mi znacznie szybciej rozwiązać istniejące problemy, poświęciłbym czas na przyswojenie go. Ale mogę wypisać ANSI-89 SQL bez zastanawiania się nad składnią. Płacą mi za rozwiązywanie problemów - myślenie o składni SQL to strata czasu i pieniędzy pracodawcy.

Pewnego dnia, młody Grasshopperze, będziesz bronić swojego używania składni ANSI-92 SQL przed narzekaniem młodych ludzi, że powinieneś używać SQL3 (lub czegoś podobnego). A wtedy zrozumiesz. :-)

JPLemme
źródło
2
Podejście opisane tutaj brzmi DUŻO jak szkoła myślenia „napraw to, gdy się psuje”, unikając idei konserwacji zapobiegawczej. Otrzymujesz wynagrodzenie za rozwiązywanie problemów, tak, ale także za zapewnienie większej wartości swojej firmie. ANSI-89 w twoim przypadku zapewnia większą wartość w krótkim okresie, ale na dłuższą metę nie inwestowanie czasu w ANSI-92 będzie droższą opcją.
Travis,
Trzymanie się tego, co zawsze robiłeś, wiąże się z kosztami dla biedaka, który musi utrzymać twój kod, gdy cię nie ma. Nie oznacza to, że powinieneś przestawić się na smak miesiąca, ale przyjęcie najlepszych praktyk prawie zawsze opłaca się w utrzymaniu.
Nie przełączę się na Excela (gdzie możesz zrobić wszystko trzema kliknięciami myszy lub mniej), ponieważ zapamiętałem tysiące poleceń Lotus 123, których potrzebuję i czuję się komfortowo z nich! Hah!
Charles Bretana
2

Miałem zapytanie, które zostało pierwotnie napisane dla SQL Server 6.5, które nie obsługuje składni złączenia SQL 92, tj

select foo.baz
from foo
  left outer join bar
  on foo.a = bar.a

został zamiast tego zapisany jako

select foo.baz
from foo, bar
where foo.a *= bar.a

Zapytanie istniało już od jakiegoś czasu, a odpowiednie dane zostały zgromadzone, aby wykonać zapytanie zbyt wolno, trwało około 90 sekund. Zanim pojawił się ten problem, przeprowadziliśmy aktualizację do SQL Server 7.

Po grzebaniu w indeksach i innych żartach na Wielkanoc, zmieniłem składnię łączenia na zgodną z SQL 92. Czas zapytania spadł do 3 sekund.

Jest dobry powód, aby się zmienić.

Opublikowano ponownie stąd .

Dave
źródło
1

Potrafię odpowiedzieć z punktu widzenia przeciętnego programisty, znając tylko tyle SQL, aby zrozumieć obie składnie, ale wciąż szukam w Google dokładnej składni wstawiania za każdym razem, gdy tego potrzebuję ... :-P (nie robię SQL przez cały dzień , po prostu od czasu do czasu naprawiając niektóre problemy).

Cóż, właściwie, uważam, że pierwsza forma jest bardziej intuicyjna, bez widocznej hierarchii między dwiema tabelami. Fakt, że nauczyłem się SQL prawdopodobnie ze starych książek, pokazując pierwszą formę, prawdopodobnie nie pomaga ... ;-)
I pierwsza wzmianka, którą znajduję w wyszukiwaniu sql select w Google (która zwraca dla mnie głównie francuskie odpowiedzi ... ) najpierw pokazuje starszą formę (następnie wyjaśnij drugą).

Podaję tylko kilka wskazówek na pytanie „dlaczego”… ^ _ ^ Powinienem przeczytać dobrą, nowoczesną książkę (agnostyk DB) na ten temat. Jeśli ktoś ma sugestie ...

PhiLho
źródło
1

Nie mogę mówić w imieniu wszystkich szkół, ale na moim uniwersytecie, kiedy robiliśmy moduł SQL naszego kursu, nie uczyli ANSI-92, uczyli ANSI-89 - i to na starym systemie VAX! Nie byłem narażony na ANSI-92, dopóki nie zacząłem kopać w programie Access, budując kilka zapytań za pomocą projektanta zapytań, a następnie zagłębiając się w kod SQL. Zdając sobie sprawę, że nie miałem pojęcia, jak kończy się łączenie, ani implikacje składni, zacząłem szukać głębiej, aby móc to zrozumieć.

Biorąc pod uwagę, że dostępna dokumentacja w wielu przypadkach nie jest dokładnie intuicyjna, a ludzie mają tendencję do trzymania się tego, co wiedzą, aw wielu przypadkach nie starają się uczyć więcej niż potrzebują, aby wykonać swoją pracę, łatwo zrozumieć, dlaczego adopcja trwa tak długo.

Oczywiście są tacy ewangeliści techniczni, którzy lubią majsterkować i rozumieć, i są to zazwyczaj te typy, które przyjmują „nowsze” zasady i próbują nawrócić resztę.

Co dziwne, wydaje mi się, że wielu programistów wychodzi ze szkoły i przestaje robić postępy; myśląc, że skoro tego ich uczono, tak się to robi. Dopiero gdy zdejmiesz migawki, zdasz sobie sprawę, że szkoła miała tylko nauczyć cię podstaw i dać ci wystarczająco dużo zrozumienia, aby samemu nauczyć się reszty, i że tak naprawdę ledwo zarysowałeś powierzchnię tego, co trzeba wiedzieć; teraz twoim zadaniem jest kontynuować tę ścieżkę.

Oczywiście to tylko moja opinia oparta na moim doświadczeniu.

BenAlabaster
źródło
To nie tylko programiści. W wielu dziedzinach trudno jest przekonać ludzi do przekwalifikowania się po osiągnięciu ugruntowanej pozycji zawodowej. Są oczywiście wyjątkowe jednostki, zakładam, że w każdej dziedzinie są takie same proporcje.
Bill Karwin,
2
Trudno przekonać kogoś do odejścia od czegoś, co odniosło sukces, na coś innego, co nie przynosi żadnych korzyści. Nasza strona domu .net zmieniła się z 1,0 na 3,5 i każdy krok pomiędzy nimi z ZERO cajoling. Każda nowa wersja była lepsza. Nie mogę powiedzieć tego samego tutaj.
1

1) Standardowy sposób zapisywania OUTER JOIN w porównaniu z * = lub (+) =

2) NATURALNE DOŁĄCZENIE

3) W zależności od silnika bazy danych, ANSI-92 jest bardziej optymalny.

4) Optymalizacja ręczna:

Powiedzmy, że mamy następną składnię (ANSI-89):

(1)select * from TABLE_OFFICES to,BIG_TABLE_USERS btu
where to.iduser=tbu.iduser and to.idoffice=1

Można to zapisać jako:

(2)select * from TABLE_OFFICES to
inner join BIG_TABLE_USERS btu on to.iduser=tbu.iduser
where to.idoffice=1

Ale także jako:

(3)select * from TABLE_OFFICES to
inner join BIG_TABLE_USERS btu on to.iduser=tbu.iduser and to.idoffice=1

Wszystkie (1), (2), (3) zwracają ten sam wynik, jednak są one inaczej optymalizowane, zależy to od silnika bazy danych, ale większość z nich:

  • (1) to silnik bazy danych decyduje o optymalizacji.
  • (2) łączy obie tabele, a następnie filtruje według biura.
  • (3) filtruje BIG_TABLE_USERS używając idoffice, a następnie łączy obie tabele.

5) Dłuższe zapytania są mniej kłopotliwe.

magallanes
źródło
1

Powody, dla których ludzie używają ANSI-89 z mojego praktycznego doświadczenia ze starymi i młodymi programistami i stażystami oraz świeżymi absolwentami:

  • Uczą się SQL z istniejącego kodu, który widzą (zamiast z książek) i uczą się ANSI-89 z kodu
  • ANSI-89, ponieważ mniej pisze
  • Nie myślą o tym i używają jednego lub drugiego stylu, a nawet nie wiedzą, który z nich jest uważany za nowy czy stary, i też się tym nie przejmuje
  • Pomysł, że kod jest również komunikacją z następnym programistą, który będzie go obsługiwał, nie istnieje. Myślą, że rozmawiają z komputerem, a komputer nie dba o to.
  • Sztuka „czystego kodowania” jest nieznana
  • Znajomość języka programowania i SQL jest tak słaba, że ​​kopiują i wklejają razem to, co znaleźli gdzie indziej
  • Osobiste preferencje

Osobiście wolę ANSI-92 i zmieniam każde zapytanie, które widzę w składni ANSI-89, czasami tylko po to, aby lepiej zrozumieć instrukcję SQL. Ale zdałem sobie sprawę, że większość ludzi, z którymi pracuję, nie ma wystarczających umiejętności, aby pisać złączenia na wielu tabelach. Kodują najlepiej, jak potrafią i używają tego, co zapamiętali, gdy po raz pierwszy napotkali instrukcję SQL.

hol
źródło
1

Oto kilka punktów porównujących SQL-89 i SQL-92 oraz wyjaśniających pewne nieporozumienia w innych odpowiedziach.

  1. NATURAL JOINSto okropny pomysł. Są niejawne i wymagają metainformacji o tabeli. Nic w SQL-92 nie wymaga ich użycia, więc po prostu je zignoruj . Nie mają one znaczenia dla tej dyskusji.
  2. USING to świetny pomysł, ma dwa efekty:
    1. Tworzy tylko jedną kolumnę w zestawie wyników z equijoin.
    2. Wymusza rozsądną i rozsądną konwencję. W SQL-89 ludzie piszą kolumny idw obu tabelach. Po dołączeniu do tabel staje się to niejednoznaczne i wymaga jawnego aliasingu. Co więcej, idznaki na złączeniu prawie na pewno miały inne dane. Jeśli łączysz osobę z firmą, musisz teraz utworzyć alias jeden iddo person_idi jeden iddo company_id, bez których sprzężenie dałoby dwie niejednoznaczne kolumny. Użycie unikalnego globalnie identyfikatora dla klucza zastępczego tabeli jest konwencją, zgodnie z którą standardowo nagradza USING.
  3. Składnia SQL-89 jest niejawna CROSS JOIN. A CROSS JOINnie redukuje zbioru, ale pośrednio go powiększa. FROM T1,T2jest tym samym, co FROM T1 CROSS JOIN T2, tworzy sprzężenie kartezjańskie, które zwykle nie jest tym, czego chcesz. Posiadanie selektywności pozwalającej zredukować to do odległego WHEREwarunku oznacza, że ​​bardziej prawdopodobne jest popełnienie błędów podczas projektowania.
  4. ,Jawne JOINkody SQL-89 i SQL-92 mają inny priorytet. JOINma wyższy priorytet. Co gorsza, niektóre bazy danych, takie jak MySQL, źle to rozumiały przez bardzo długi czas. . Tak więc mieszanie tych dwóch stylów jest złym pomysłem, a obecnie o wiele bardziej popularnym stylem jest styl SQL-92.
Evan Carroll
źródło
1) Jeśli przestudiujesz model relacyjny, z pewnością docenisz, że dołączenie do świetnego pomysłu jest nie tylko naturalne, ale jest to jedyny rodzaj połączenia, jakiego potrzebujesz. 2) Patrz 1, tzn. Niepotrzebne. 3) Niezależnie od składni ( obie są składnią SQL-92), operatorem relacyjnym jest iloczyn (mnożenie), czyli nie jest to łączenie (złączenie kartezjańskie nie jest nawet rzeczą). 4. Patrz 1 tj. Nie jest potrzebne.
kiedy
0

Oracle w ogóle nie implementuje standardu ANSI-92. Miałem kilka problemów, między innymi dlatego, że tabele danych w Oracle Apps są tak dobrze wyposażone w kolumny. Jeśli liczba kolumn w połączeniach przekracza około 1050 kolumn (co jest bardzo łatwe w aplikacjach), otrzymasz ten fałszywy błąd, który nie ma absolutnie żadnego logicznego sensu:

ORA-01445: cannot select ROWID from a join view without a key-preserved table.

Ponowne napisanie zapytania w celu użycia składni łączenia w starym stylu sprawia, że ​​problem znika, co wydaje się wskazywać palcem winy bezpośrednio na implementację złączeń ANSI-92.

Dopóki nie napotkałem tego problemu, byłem niezłomnym promotorem ASNI-92, ze względu na korzyści w zmniejszaniu szansy przypadkowego łączenia krzyżowego, co jest zbyt łatwe do wykonania przy użyciu składni starego stylu.

Teraz jednak jest mi o wiele trudniej nalegać na to. Wskazują na złą implementację Oracle i mówią „Zrobimy to po swojemu, dzięki”.

Jonathan
źródło
1
Wykonanie połączenia krzyżowego może być łatwe, jest to również coś, co nie dzieje się spontanicznie iz pewnością nie jest niejednoznaczne. Każdy przyzwoity programista SQL mógłby to zauważyć. Ale USING i NATURAL JOIN to kusicielki, które wzywają cię i rozbijają twoją małą łódkę o skały udręki i nieszczęścia.
1
Chodziło mi o to, że łatwiej jest pomyślnie utworzyć przypadkowe sprzężenie krzyżowe, pomijając klauzulę where, która łączy dwie tabele razem. W ANSI-92 połączenie krzyżowe musi być celowe. Ale zgadzam się, że NATURALNE JOIN to obrzydliwość. :)
Jonathan
Zrozumiałem twój punkt widzenia. Ale to nie dzieje się nagle. Podczas debugowania zapytania można zauważyć problem i go naprawić. Jeśli używasz sprzężenia naturalnego, bez zmian -wszystkich- w samym zapytaniu, może się ono zmienić z powodu zmiany tabeli.
0

Nowy standard SQL dziedziczy wszystko z poprzedniego standardu, czyli „kajdany zgodności”. Tak więc styl łączenia „stary” / „rozdzielany przecinkami” / „niekwalifikowany” jest całkowicie poprawnym sytaxem SQL-92.

Teraz twierdzę, że SQL-92 NATURAL JOINjest jedynym złączeniem, którego potrzebujesz. Na przykład uważam, że jest lepszy od inner jointego, że nie generuje zduplikowanych kolumn - nie ma już zmiennych zakresu w SELECTklauzulach, aby ujednoznacznić kolumny! Ale nie mogę oczekiwać, że zmienię każde serce i umysł, więc muszę pracować z programistami, którzy będą nadal przyjmować to, co osobiście uważam za starsze style łączenia (a mogą nawet odnosić się do zmiennych zakresu jako „aliasy”!). Taka jest natura pracy zespołowej, a nie działania w próżni.

Jedną z krytyki języka SQL jest to, że ten sam wynik można uzyskać za pomocą kilku semantycznie równoważnych składni (niektóre używają algebry relacyjnej, inne używają rachunku relacyjnego), gdzie wybór `` najlepszej '' sprowadza się po prostu do osobistego stylu . Więc czuję się równie dobrze z połączeniami „w starym stylu”, jak z INNER. To, czy poświęcę trochę czasu, aby je przepisać, NATURALzależy od kontekstu.

onedaywhen
źródło