PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

SQL функцията е много бавна в сравнение със заявка без обвивка на функция

user

Докато пренаписвах вашата функция, разбрах, че сте добавили псевдоними на колони тук:

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

.. което не би направило нищо да започнем с това, тъй като тези псевдоними са невидими извън функцията и не се препращат вътре във функцията. Така че те биха били игнорирани. За целите на документацията по-добре използвайте коментар.

Но също така прави заявката ви невалидна , защото user е напълно запазена дума и не може да се използва като псевдоним на колона, освен ако не е в двойни кавички.

Странно, в моите тестове функцията изглежда работи с невалиден псевдоним. Вероятно защото се игнорира (?). Но не съм сигурен, че това не може да има странични ефекти.

Вашата функция е пренаписана (иначе еквивалентна):

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;

Очевидно STABLE ключова дума промени резултата. Променливост на функцията не трябва да е проблем в тестовата ситуация, която описвате. Настройката обикновено не печели едно, изолирано извикване на функция. Прочетете подробностите в ръководството. Също така, стандартен EXPLAIN не показва планове за заявки за това, което се случва вътре функции. Можете да използвате допълнителния модул auto-explain за това:

  • План на заявка Postgres на извикване на UDF, написано в pgpsql

Имате много странно разпределение на данните :

таблицата auth_web_events има 100000000 записа, auth_user->2 записа, клиенти-> 1 запис

Тъй като не сте дефинирали друго, функцията приема приблизителна оценка от 1000 реда да бъдат върнати. Но вашата функция всъщност връща само 2 реда . Ако всичките ви обаждания връщат само (в близост до) 2 реда, просто декларирайте това с добавен ROWS 2 . Може да промени плана на заявката за VOLATILE вариант също (дори ако STABLE все пак е правилният избор тук).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Най-добрите ресурси за обучение и обучение на PostgreSQL

  2. запазване на обект на python в таблица на postgres с туршия

  3. Разделете дадения низ и подгответе изявление за case

  4. Как да изброите всички бази данни с помощта на PostgreSQL

  5. Проблеми при настройката на персонализиран първичен ключ при миграция на Rails 4