user
Podczas przepisywania Twojej funkcji zdałem sobie sprawę, że dodałeś tutaj aliasy kolumn:
SELECT
...
auth_user.email AS user,
customers.name AS customer,
.. co nic nie zrobi na początek, ponieważ te aliasy są niewidoczne na zewnątrz funkcji i nie są przywoływane wewnątrz funkcji. Byli więc zignorowani. Do celów dokumentacji lepiej użyj komentarza.
Ale powoduje to również, że Twoje zapytanie jest nieważne , ponieważ user
to całkowicie słowo zastrzeżone i nie może być używany jako alias kolumny, chyba że jest cytowany w podwójnym cudzysłowie.
Co dziwne, w moich testach funkcja wydaje się działać z nieprawidłowym aliasem. Prawdopodobnie dlatego, że jest ignorowany (?). Ale nie jestem pewien, czy to nie może mieć skutków ubocznych.
Twoja funkcja przepisana (w innym przypadku równoważna):
CREATE OR REPLACE FUNCTION get_web_events_by_userid(int)
RETURNS TABLE(
id int
, time_stamp timestamptz
, description text
, origin text
, userlogin text
, customer text
, client_ip inet
) AS
$func$
SELECT w.id
, w.time_stamp
, w.description
, w.origin
, u.email -- AS user -- make this a comment!
, c.name -- AS customer
, w.client_ip
FROM public.auth_user u
JOIN public.auth_web_events w ON w.user_id_fk = u.id
JOIN public.customers c ON c.id = u.customer_id_fk
WHERE u.id = $1 -- reverted the logic here
ORDER BY w.id DESC
$func$ LANGUAGE sql STABLE;
Oczywiście STABLE
słowo kluczowe zmieniło wynik. Zmienność funkcji nie powinno stanowić problemu w sytuacji testowej, którą opisujesz. Ustawienie to zwykle nie przynosi korzyści w przypadku pojedynczego, izolowanego wywołania funkcji. Przeczytaj szczegóły w instrukcji. Również standardowe EXPLAIN
nie pokazuje planów zapytań dotyczących tego, co dzieje się w środku Funkcje. Możesz zastosować dodatkowy moduł automatyczne wyjaśnienie za to:
- Plan zapytań Postgres wywołania UDF napisany w pgpsql
Masz bardzo dziwną dystrybucję danych :
Tabela auth_web_events ma 100000000 rekordów, auth_user->2 rekordy, customers->1 rekord
Ponieważ nie zdefiniowałeś inaczej, funkcja zakłada oszacowanie 1000 wierszy zostać zwrócone. Ale Twoja funkcja w rzeczywistości zwraca tylko 2 wiersze . Jeśli wszystkie twoje połączenia zwracają tylko (w pobliżu) 2 wiersze, po prostu zadeklaruj to z dodanym ROWS 2
. Może zmienić plan zapytań dla VOLATILE
również wariant (nawet jeśli STABLE
i tak jest to właściwy wybór).