PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

SQL-Funktion sehr langsam im Vergleich zu Abfragen ohne Funktionswrapper

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).