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
все пак е правилният избор тук).