sql >> Database teknologi >  >> RDS >> PostgreSQL

SQL-funktion meget langsom sammenlignet med forespørgsel uden funktionsindpakning

user

Mens jeg skrev din funktion om, indså jeg, at du tilføjede kolonnealiaser her:

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

.. som ikke ville gøre noget til at begynde med, da disse aliaser er usynlige uden for funktionen og ikke refereres til inde i funktionen. Så de ville blive ignoreret. Brug en kommentar til dokumentationsformål.

Men det gør også din forespørgsel ugyldig , fordi user er et fuldstændig reserveret ord og kan ikke bruges som kolonnealias, medmindre der er anført dobbelte citater.

Mærkeligt nok ser funktionen i mine test ud til at fungere med det ugyldige alias. Sandsynligvis fordi den er ignoreret (?). Men jeg er ikke sikker på, at dette ikke kan have bivirkninger.

Din funktion er omskrevet (ellers tilsvarende):

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;

Det er klart, at STABLE søgeord ændrede resultatet. Funktionsvolatilitet burde ikke være et problem i den testsituation, du beskriver. Indstillingen tjener normalt ikke et enkelt, isoleret funktionskald. Læs detaljerne i manualen. Også standard EXPLAIN viser ikke forespørgselsplaner for, hvad der foregår inde i funktioner. Du kan bruge det ekstra modul automatisk forklaring for det:

  • Postgres-forespørgselsplan for en UDF-invokation skrevet i pgpsql

Du har en meget mærkelig datadistribution :

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

Da du ikke har defineret andet, antager funktionen et estimat på 1000 rækker skal returneres. Men din funktion returnerer faktisk kun 2 rækker . Hvis alle dine opkald kun returnerer (i nærheden af) 2 rækker, skal du blot erklære det med en tilføjet ROWS 2 . Ændrer muligvis forespørgselsplanen for VOLATILE variant også (selvom hvis STABLE er det rigtige valg alligevel her).



  1. Forståelse af SQL Server Always Encrypted

  2. 2018 i anmeldelse:7 MariaDB-milepæle, du måske er gået glip af

  3. Sammenligning af SQL Server int vs nvarchar på ydeevne?

  4. Forespørgsel for kun at hente tal fra en streng