sql >> Databasteknik >  >> RDS >> PostgreSQL

SQL-funktion mycket långsam jämfört med fråga utan funktionsomslag

user

När jag skrev om din funktion insåg jag att du lagt till kolumnalias här:

SELECT 
  ...
  auth_user.email AS user, 
  customers.name AS customer,

.. som inte skulle göra någonting till att börja med, eftersom dessa alias är osynliga utanför funktionen och inte refereras inuti funktionen. Så de skulle ignoreras. För dokumentationsändamål är det bättre att använda en kommentar.

Men det gör också din fråga ogiltig , eftersom user är ett helt reserverat ord och kan inte användas som kolumnalias om det inte är dubbla citattecken.

Konstigt nog verkar funktionen i mina tester fungera med det ogiltiga aliaset. Förmodligen för att den ignoreras (?). Men jag är inte säker på att detta inte kan ha biverkningar.

Din funktion omskriven (annars likvärdig):

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;

Uppenbarligen är STABLE sökord ändrade resultatet. Funktionsvolatilitet borde inte vara ett problem i den testsituation du beskriver. Inställningen tjänar normalt inte ett enda, isolerat funktionsanrop. Läs detaljerna i manualen. Dessutom standard EXPLAIN visar inte frågeplaner för vad som händer inuti funktioner. Du kan använda tilläggsmodulen auto-explain för det:

  • Postgres-frågeplan för en UDF-anrop skriven i pgpsql

Du har en mycket udda datadistribution :

Tabellen auth_web_events har 100000000 poster, auth_user->2 poster, kunder-> 1 post

Eftersom du inte definierade något annat antar funktionen en uppskattning av 1000 rader ska återlämnas. Men din funktion returnerar faktiskt bara 2 rader . Om alla dina samtal bara returnerar (i närheten av) 2 rader, deklarera bara det med en tillagd ROWS 2 . Kan ändra frågeplanen för VOLATILE variant också (även om STABLE är rätt val ändå här).



  1. IllegalStateException:databas redan stängd (med ViewPager)

  2. Hur kan jag fixa MySQL-fel #1064?

  3. Ställa in Active Data Guard Physical Standby i RAC One Node Architecture – Del 1

  4. Hur man formaterar SQLite-resultat som en tabell