user
Durante la riscrittura della tua funzione mi sono reso conto che hai aggiunto alias di colonna qui:
SELECT
...
auth_user.email AS user,
customers.name AS customer,
.. che non farebbe nulla tanto per cominciare, poiché quegli alias sono invisibili all'esterno della funzione e non referenziati all'interno della funzione. Quindi verrebbero ignorati. Ai fini della documentazione meglio utilizzare un commento.
Ma rende anche la tua query non valida , perché user
è una parola completamente riservata e non può essere utilizzato come alias di colonna a meno che non sia doppiato tra virgolette.
Stranamente, nei miei test la funzione sembra funzionare con l'alias non valido. Probabilmente perché è ignorato (?). Ma non sono sicuro che questo non possa avere effetti collaterali.
La tua funzione riscritta (altrimenti equivalente):
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;
Ovviamente, il STABLE
la parola chiave ha cambiato il risultato. Volatilità delle funzioni non dovrebbe essere un problema nella situazione di test che descrivi. L'impostazione normalmente non giova a una singola chiamata di funzione isolata. Leggi i dettagli nel manuale. Inoltre, lo standard EXPLAIN
non mostra i piani di query per ciò che sta accadendo dentro funzioni. Potresti utilizzare il modulo aggiuntivo spiegazione automatica per quello:
- Piano di query Postgres di una chiamata UDF scritta in pgpsql
Hai una distribuzione dei dati molto strana :
La tabella auth_web_events ha 100000000 record, auth_user->2 record, clients-> 1 record
Poiché non hai definito diversamente, la funzione presuppone una stima di 1000 righe da restituire. Ma la tua funzione in realtà restituisce solo 2 righe . Se tutte le tue chiamate restituiscono solo (in prossimità di) 2 righe, dichiaralo semplicemente con un ROWS 2
aggiunto . Potrebbe cambiare il piano di query per VOLATILE
anche variante (anche se STABLE
è comunque la scelta giusta qui).