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
LISTEN
i NOTIFY
porozmawiać 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 SELECT
całego widoku, WHERE
klauzule 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:
WHERE
Potrzebne są parametry, których nie można wyrazić jako proste klauzule, podobnie jak parametr wWITH
wyrażeniu
- Chcesz barierę bezpieczeństwa za pomocą
SECURITY DEFINER
funkcji, a security_barrier
widoki 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 STABLE
lub IMMUTABLE
(i nie zadeklarowane STRICT
lub 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 CASE
instrukcje, 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
EXECUTE
instrukcji
- Gdy chcesz
RAISE
błę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ą
EXCEPTION
bloków zamiast zamykać całą transakcję na błąd
- Złożona logika warunkowa, która nie pasuje
CASE ... WHEN
zbyt dobrze
- Dużo ponownego wykorzystania obliczonych wartości, do których nie można się zmieścić
WITH
i 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.