Języki proceduralne PostgreSQL - różnice między PL / pgSQL a SQL

20

Czy ktoś może streścić różnice między:

http://www.postgresql.org/docs/9.1/static/xfunc-sql.html

i

http://www.postgresql.org/docs/9.1/static/plpgsql.html

?

Główne punkty:

  • różnice koncepcyjne
  • biorąc pod uwagę problem rodziny, wygoda użytkowania
  • kwestie polityczne
Gismo Ranas
źródło
1
Po pierwsze, funkcje SQL (znane również jako język zapytań) nie obejmują żadnego z języków proceduralnych PostgreSQL. Po drugie, już znalazłeś najlepsze źródło, w którym można znaleźć odpowiedzi na swoje pytania (z wyjątkiem ostatniego - co dokładnie oznacza „kwestie polityczne”?)
dezso
Poprosiłem o podsumowanie wszystkich głównych problemów, niekoniecznie wykorzystując wklejoną dokumentację, ale także osobiste wrażenia. Te linki mają na celu upewnienie się, że wszyscy rozumieją, o co chodzi w tym pytaniu.
Gismo Ranas,
Nie bierz tego za atak, ale kiedy je przeczytasz, możesz je streścić :) W przeciwnym razie twoje pytanie jest nieco szerokie, ale przy odrobinie czasu postaram się zebrać kilka myśli.
dezso,
1
Nie zaniedbuj innych języków proceduralnych. W szczególności PL / Perl jest niezwykle przydatny w obszarach, w których PL / PgSQL jest zbyt ograniczony; PL / Pythonu wykonuje to zadanie, jeśli wolisz Python, ale nie oferuje modelu bezpieczeństwa, takiego jak PL / Perl. Istnieje również PL / V8 (JavaScript) jako dodatek.
Craig Ringer
1
Cześć cataldo - Chciałbym tylko powitać Cię na stronie, ponieważ jest to twoje pierwsze pytanie tutaj. Dzięki za opublikowanie i mam nadzieję, że zostaniesz.
Jack Douglas,

Odpowiedzi:

27

Funkcje PL / PgSQL i zwykły SQL są częścią większego zestawu narzędzi i powinny być przeglądane w tym kontekście. Zwykle myślę o tym w kategoriach rosnącej siły połączonej z rosnącą złożonością i kosztami, w której powinieneś użyć najprostszego narzędzia, które dobrze wykona zadanie:

  • W miarę możliwości korzystaj z widoków
  • Jeśli widok nie jest odpowiedni, użyj funkcji SQL
  • Tam, gdzie funkcja SQL nie jest odpowiednia, użyj PL / PgSQL.
  • Jeśli PL / PgSQL jest zbyt ograniczony lub niewystarczająco ekspresyjny, użyj PL / Perl, PL / Python, PL / V8, PL / Java lub cokolwiek innego
  • ... i gdzie brak PL będzie wykonać zadanie, należy użyć zewnętrznego programu i ewentualnie LISTENi NOTIFYporozmawiać z nim.

Bardzo często widok jest wystarczający, jeśli uważasz, że potrzebna jest funkcja. Nawet jeśli jest to bardzo kosztowne dla SELECTcałego widoku, WHEREklauzule w zapytaniu odnoszące się do widoku są zwykle spychane do widoku i mogą powodować bardzo różne plany zapytań. Często miałem duże ulepszenia wydajności od konwersji funkcji SQL na widoki.

Główny czas, w którym okazuje się, że nie możesz użyć widoku i powinieneś rozważyć funkcję SQL, to:

  • WHEREPotrzebne są parametry, których nie można wyrazić jako proste klauzule, podobnie jak parametr wWITH wyrażeniu
  • Chcesz barierę bezpieczeństwa za pomocą SECURITY DEFINERfunkcji, a security_barrierwidoki w PostgreSQL 9.2 i nowszych nie są wystarczające dla twoich potrzeb;
  • Potrzebujesz parametrów, które nie są spychane przez sub-klauzule widoku przez optymalizator i chcesz kontrolować je bardziej bezpośrednio; lub
  • Istnieje wiele parametrów lub wiele powtórzeń parametrów, więc napisanie zapytania jako widoku jest niepraktyczne.

W przypadku większości tych zadań zwykła funkcja SQL działa dobrze i często jest łatwiejsza do odczytania niż PL / PgSQL. Funkcje SQL zadeklarowane STABLElub IMMUTABLE(i nie zadeklarowane STRICTlub SECURITY DEFINER) można również wstawić do instrukcji wywołującej. Pozbywa się to narzutu wywołania funkcji, a czasem może również przynieść ogromne korzyści w zakresie wydajności, gdy warunek WHERE w funkcji wywołującej zostaje zepchnięty do funkcji SQL przez optymalizator. Korzystaj z funkcji SQL, gdy są one wystarczające do wykonania zadania.

Głównymi czasami, gdy funkcje SQL nie wykonają zadania, jest potrzeba dużej logiki. Jeśli operacje / then / else, których nie można wyrazić jako CASEinstrukcje, przydaje się wiele ponownego wykorzystania obliczonych wyników, budowanie wartości z porcji, obsługa błędów itp. PL / PgSQL. Wybierz PL / PgSQL, gdy nie możesz korzystać z funkcji SQL lub są one słabo dopasowane, na przykład:

  • Dynamiczny SQL i dynamiczny DDL za pośrednictwem EXECUTEinstrukcji
  • Gdy chcesz RAISEbłędy / ostrzeżenia dla dzienników lub klienta
  • Gdy potrzebujesz obsługi wyjątków - możesz wychwytywać i obsługiwać błędy za pomocą EXCEPTIONbloków zamiast zamykać całą transakcję na błąd
  • Złożona logika warunkowa, która nie pasuje CASE ... WHENzbyt dobrze
  • Dużo ponownego wykorzystania obliczonych wartości, do których nie można się zmieścić WITHi CTE
  • Budowanie rekordów dynamicznych
  • Musisz wykonać akcję po wygenerowaniu zestawu wyników

W przypadku typowych wyrażeń tabelowych (CTE), szczególnie zapisywalnych CTE WITH RECURSIVE, okazuje się, że używam PL / PgSQL o wiele mniej niż kiedyś, ponieważ SQL jest o wiele bardziej ekspresyjny i potężny. Korzystam teraz z widoków i zwykłych funkcji SQL. Warto pamiętać, że zwykłe funkcje SQL mogą zawierać więcej niż jedną instrukcję; ostatnia instrukcja jest wynikiem funkcji.

Craig Ringer
źródło
Bardzo dobrze powiedziane! (dodatkowy, choć wirtualny +1 za wzmiankę o zapisywalnych CTE)
dezso
Te odpowiedzi wyjaśniają również, dlaczego niektóre funkcje wymagają ogrodzenia optymalizacyjnego .
Eonil
8

plpgsqljest pełnoprawnym językiem proceduralnym, ze zmiennymi, zapętlonymi konstrukcjami itp. SQLFunkcja jest po prostu podzapytaniem. Funkcja SQL, jeśli jest zadeklarowana STABLElub IMMUTABLEnie jest również zadeklarowana STRICT, często może zostać wstawiona do zapytania wywołującego, tak jakby była zapisana przy każdym odwołaniu.

kgrittn
źródło