user
Mens jeg skrev din funktion om, indså jeg, at du tilføjede kolonnealiaser her:
SELECT
...
auth_user.email AS user,
customers.name AS customer,
.. som ikke ville gøre noget til at begynde med, da disse aliaser er usynlige uden for funktionen og ikke refereres til inde i funktionen. Så de ville blive ignoreret. Brug en kommentar til dokumentationsformål.
Men det gør også din forespørgsel ugyldig , fordi user
er et fuldstændig reserveret ord og kan ikke bruges som kolonnealias, medmindre der er anført dobbelte citater.
Mærkeligt nok ser funktionen i mine test ud til at fungere med det ugyldige alias. Sandsynligvis fordi den er ignoreret (?). Men jeg er ikke sikker på, at dette ikke kan have bivirkninger.
Din funktion er omskrevet (ellers tilsvarende):
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;
Det er klart, at STABLE
søgeord ændrede resultatet. Funktionsvolatilitet burde ikke være et problem i den testsituation, du beskriver. Indstillingen tjener normalt ikke et enkelt, isoleret funktionskald. Læs detaljerne i manualen. Også standard EXPLAIN
viser ikke forespørgselsplaner for, hvad der foregår inde i funktioner. Du kan bruge det ekstra modul automatisk forklaring for det:
- Postgres-forespørgselsplan for en UDF-invokation skrevet i pgpsql
Du har en meget mærkelig datadistribution :
auth_web_events-tabellen har 100000000 poster, auth_user->2 poster, kunder-> 1 post
Da du ikke har defineret andet, antager funktionen et estimat på 1000 rækker skal returneres. Men din funktion returnerer faktisk kun 2 rækker . Hvis alle dine opkald kun returnerer (i nærheden af) 2 rækker, skal du blot erklære det med en tilføjet ROWS 2
. Ændrer muligvis forespørgselsplanen for VOLATILE
variant også (selvom hvis STABLE
er det rigtige valg alligevel her).