PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Função SQL muito lenta em comparação com a consulta sem wrapper de função


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).