user
Tijdens het herschrijven van je functie realiseerde ik me dat je hier kolomaliassen hebt toegevoegd:
SELECT
...
auth_user.email AS user,
customers.name AS customer,
.. die niets zou doen om te beginnen, aangezien die aliassen onzichtbaar zijn buiten de functie en er niet naar wordt verwezen binnen de functie. Ze zouden dus genegeerd worden. Gebruik voor documentatiedoeleinden beter een opmerking.
Maar het maakt uw zoekopdracht ook ongeldig , omdat user
is een volledig gereserveerd woord en kan niet worden gebruikt als kolomalias tenzij tussen dubbele aanhalingstekens.
Vreemd genoeg lijkt de functie in mijn tests te werken met de ongeldige alias. Waarschijnlijk omdat het genegeerd wordt (?). Maar ik weet niet zeker of dit geen bijwerkingen kan hebben.
Uw functie herschreven (anders equivalent):
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;
Het is duidelijk dat de STABLE
trefwoord veranderde de uitkomst. Functievolatiliteit zou geen probleem moeten zijn in de testsituatie die u beschrijft. De instelling profiteert normaal gesproken niet van een enkele, geïsoleerde functieaanroep. Lees details in de handleiding. Ook standaard EXPLAIN
toont geen zoekplannen voor wat er binnen gebeurt functies. Je zou de extra module auto-explain kunnen gebruiken daarvoor:
- Postgres-queryplan van een UDF-aanroep geschreven in pgpsql
U heeft een zeer vreemde gegevensdistributie :
auth_web_events tabel heeft 100000000 records, auth_user->2 records, klanten-> 1 record
Aangezien je niet anders hebt gedefinieerd, gaat de functie uit van een schatting van 1000 rijen wordt teruggestuurd. Maar uw functie retourneert eigenlijk slechts 2 rijen . Als al uw oproepen slechts (in de buurt van) 2 rijen terugkeren, declareert u dat gewoon met een toegevoegde ROWS 2
. Kan het zoekplan voor de VOLATILE
wijzigen variant ook (zelfs als STABLE
is hier sowieso de juiste keuze).