user
Ao reescrever sua função, percebi que você adicionou aliases de coluna aqui:
SELECT
...
auth_user.email AS user,
customers.name AS customer,
.. que não faria nada para começar, uma vez que esses aliases são invisíveis fora da função e não referenciados dentro da função. Assim, seriam ignorados. Para fins de documentação, é melhor usar um comentário.
Mas também torna sua consulta inválida , porque
user
é uma palavra completamente reservada e não pode ser usado como alias de coluna, a menos que esteja entre aspas duplas. Estranhamente, em meus testes a função parece funcionar com o alias inválido. Provavelmente porque é ignorado (?). Mas não tenho certeza se isso não poderia ter efeitos colaterais.
Sua função reescrita (de outra forma equivalente):
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;
Obviamente, o
STABLE
palavra-chave alterou o resultado. Volatilidade da função não deve ser um problema na situação de teste que você descreve. A configuração normalmente não beneficia uma única chamada de função isolada. Leia os detalhes no manual. Além disso, o padrão EXPLAIN
não mostra planos de consulta para o que está acontecendo dentro funções. Você pode empregar o módulo adicional autoexplicação por isso:- Plano de consulta Postgres de uma invocação de UDF escrita em pgpsql
Você tem uma distribuição de dados muito estranha :
A tabela auth_web_events tem 100000000 registros, auth_user->2 registros, clients-> 1 registro
Como você não definiu de outra forma, a função assume uma estimativa de 1.000 linhas ser devolvido. Mas sua função está retornando apenas 2 linhas . Se todas as suas chamadas retornarem apenas (nas proximidades de) 2 linhas, apenas declare isso com um
ROWS 2
adicionado . Pode alterar o plano de consulta para o VOLATILE
variante também (mesmo se STABLE
é a escolha certa de qualquer maneira aqui).