PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Funkcja SQL jest bardzo powolna w porównaniu z zapytaniem bez opakowania funkcji

user

Podczas przepisywania Twojej funkcji zdałem sobie sprawę, że dodałeś tutaj aliasy kolumn:

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

.. co nic nie zrobi na początek, ponieważ te aliasy są niewidoczne na zewnątrz funkcji i nie są przywoływane wewnątrz funkcji. Byli więc zignorowani. Do celów dokumentacji lepiej użyj komentarza.

Ale powoduje to również, że Twoje zapytanie jest nieważne , ponieważ user to całkowicie słowo zastrzeżone i nie może być używany jako alias kolumny, chyba że jest cytowany w podwójnym cudzysłowie.

Co dziwne, w moich testach funkcja wydaje się działać z nieprawidłowym aliasem. Prawdopodobnie dlatego, że jest ignorowany (?). Ale nie jestem pewien, czy to nie może mieć skutków ubocznych.

Twoja funkcja przepisana (w innym przypadku równoważna):

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;

Oczywiście STABLE słowo kluczowe zmieniło wynik. Zmienność funkcji nie powinno stanowić problemu w sytuacji testowej, którą opisujesz. Ustawienie to zwykle nie przynosi korzyści w przypadku pojedynczego, izolowanego wywołania funkcji. Przeczytaj szczegóły w instrukcji. Również standardowe EXPLAIN nie pokazuje planów zapytań dotyczących tego, co dzieje się w środku Funkcje. Możesz zastosować dodatkowy moduł automatyczne wyjaśnienie za to:

  • Plan zapytań Postgres wywołania UDF napisany w pgpsql

Masz bardzo dziwną dystrybucję danych :

Tabela auth_web_events ma 100000000 rekordów, auth_user->2 rekordy, customers->1 rekord

Ponieważ nie zdefiniowałeś inaczej, funkcja zakłada oszacowanie 1000 wierszy zostać zwrócone. Ale Twoja funkcja w rzeczywistości zwraca tylko 2 wiersze . Jeśli wszystkie twoje połączenia zwracają tylko (w pobliżu) 2 wiersze, po prostu zadeklaruj to z dodanym ROWS 2 . Może zmienić plan zapytań dla VOLATILE również wariant (nawet jeśli STABLE i tak jest to właściwy wybór).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dlaczego liczba całkowita bez znaku nie jest dostępna w PostgreSQL?

  2. Jak zapewnić klientowi API 1 000 000 wyników z bazy danych?

  3. Używanie aktualnego czasu w UTC jako wartości domyślnej w PostgreSQL

  4. Aktualizacje oparte na niestandardowych wyzwalaczach dla PostgreSQL

  5. Dostrajanie operacji wejścia/wyjścia (I/O) dla PostgreSQL