user
En réécrivant votre fonction, j'ai réalisé que vous aviez ajouté des alias de colonne ici :
SELECT
...
auth_user.email AS user,
customers.name AS customer,
.. qui ne ferait rien pour commencer, puisque ces alias sont invisibles en dehors de la fonction et non référencés à l'intérieur de la fonction. Ils seraient donc ignorés. À des fins de documentation, mieux vaut utiliser un commentaire.
Mais cela rend également votre requête invalide , car user
est un mot entièrement réservé et ne peut pas être utilisé comme alias de colonne à moins d'être entre guillemets.
Bizarrement, dans mes tests, la fonction semble fonctionner avec l'alias invalide. Probablement parce qu'il est ignoré (?). Mais je ne suis pas sûr que cela n'ait pas d'effets secondaires.
Votre fonction réécrite (sinon équivalente) :
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;
Évidemment, le STABLE
mot-clé a changé le résultat. Volatilité de la fonction ne devrait pas être un problème dans la situation de test que vous décrivez. Le réglage ne profite normalement pas à un seul appel de fonction isolé. Lire les détails dans le manuel. En outre, la norme EXPLAIN
n'affiche pas les plans de requête pour ce qui se passe à l'intérieur les fonctions. Vous pouvez utiliser le module supplémentaire auto-explain pour cela :
- Plan de requête Postgres d'une invocation UDF écrite en pgpsql
Vous avez une distribution de données très étrange :
La table auth_web_events contient 1 000 000 enregistrements, auth_user->2 enregistrements, clients-> 1 enregistrement
Comme vous n'avez rien défini d'autre, la fonction suppose une estimation de 1 000 lignes être retourné. Mais votre fonction ne renvoie en réalité que 2 lignes . Si tous vos appels ne renvoient (aux alentours de) que 2 lignes, déclarez-le simplement avec un ROWS 2
ajouté . Peut changer le plan de requête pour le VOLATILE
variante également (même si STABLE
est le bon choix de toute façon ici).