user
Beim Umschreiben Ihrer Funktion ist mir aufgefallen, dass Sie hier Spaltenaliase hinzugefügt haben:
SELECT
...
auth_user.email AS user,
customers.name AS customer,
.. was nichts tun würde da diese Aliase außerhalb der Funktion unsichtbar sind und innerhalb der Funktion nicht referenziert werden. Sie würden also ignoriert. Verwenden Sie zu Dokumentationszwecken besser einen Kommentar.
Aber es macht Ihre Abfrage auch ungültig , weil user
ist ein völlig reserviertes Wort und kann nicht als Spaltenalias verwendet werden, es sei denn, es wird in doppelte Anführungszeichen gesetzt.
Seltsamerweise scheint die Funktion in meinen Tests mit dem ungültigen Alias zu funktionieren. Wahrscheinlich, weil es ignoriert wird (?). Aber ich bin mir nicht sicher, ob dies keine Nebenwirkungen haben könnte.
Ihre Funktion umgeschrieben (ansonsten äquivalent):
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;
Offensichtlich die STABLE
Schlüsselwort veränderte das Ergebnis. Funktionsvolatilität sollte in der von Ihnen beschriebenen Testsituation kein Problem sein. Die Einstellung profitiert normalerweise nicht von einem einzelnen, isolierten Funktionsaufruf. Details im Handbuch lesen. Auch Standard-EXPLAIN
zeigt keine Abfragepläne für das, was innerhalb vor sich geht Funktionen. Sie könnten das Zusatzmodul auto-explain einsetzen dafür:
- Postgres-Abfrageplan eines in pgpsql geschriebenen UDF-Aufrufs
Sie haben eine sehr seltsame Datenverteilung :
Die Tabelle auth_web_events hat 100000000 Datensätze, auth_user->2 Datensätze, customers-> 1 Datensatz
Da Sie nichts anderes definiert haben, geht die Funktion von einer Schätzung von 1000 Zeilen aus zurückzusenden. Aber Ihre Funktion gibt tatsächlich nur 2 Zeilen zurück . Wenn alle Ihre Aufrufe nur (in der Nähe von) 2 Zeilen zurückgeben, deklarieren Sie dies einfach mit einem hinzugefügten ROWS 2
. Kann den Abfrageplan für VOLATILE
ändern Variante (auch wenn STABLE
ist hier sowieso die richtige Wahl).