EXPLAIN ANALYZE não mostra detalhes para consultas dentro de uma função plpgsql

18

Estou usando uma função PL / pgSQL no PostgreSQL 9.3 com várias consultas complexas dentro:

create function f1()
  returns integer as
$$
declare

event tablename%ROWTYPE;
....
....

begin

FOR event IN
   SELECT * FROM tablename WHERE condition
LOOP
   EXECUTE 'SELECT f2(event.columnname)' INTO dummy_return;
END LOOP;

...

INSERT INTO ... FROM a LEFT JOIN b ... LEFT JOIN c WHERE ...

UPDATE T SET cl1 = M.cl1 FROM M WHERE M.pkcols = T.pkcols;

...

end
$$ language plpgsql;

Se eu corria EXPLAIN ANALYZE f1(), só recebia o tempo total, mas não havia detalhes. Existe uma maneira de obter resultados detalhados para todas as consultas na função?

Se as consultas na função não deveriam ser otimizadas pelo Postgres, também pediria uma explicação.

skumar
fonte
2
auto_explain.log_nested_statementspode ajudar. Veja postgresql.org/docs/9.3/static/auto-explain.html
Daniel Vérité

Respostas:

15

Primeiro, a sintaxe correta para a EXPLAINchamada precisa de a SELECT. Você não pode simplesmente escrever o nome da função vazia no SQL:

EXPLAIN ANALYZE SELECT f1();

Otimização

As funções PL / pgSQL são caixas pretas para o planejador de consultas. As consultas internas são otimizadas como outras consultas, mas separadamente e uma a uma como instruções preparadas, e o plano de execução pode ser armazenado em cache durante a sessão. Detalhes:

EXPLAIN corpos funcionais

Como o @Daniel já comentou, você pode usar o módulo adicional auto_explain para obter mais detalhes ( muitos detalhes). Instruções dentro das funções plpgsql são consideradas "instruções aninhadas". Certifique-se de definir

SET auto_explain.log_nested_statements = ON

Instruções detalhadas:

Como uma exceção à regra, funções SQL muito simples (não plpgsql) podem ser "embutidas", ou seja, o código da função é inserido na consulta externa e tudo é executado como se não houvesse uma função para começar. O plano de consulta inclui informações detalhadas nesses casos.

Erwin Brandstetter
fonte
Depois de ativar o 'auto_explain' como abaixo, carregue 'auto_explain'; defina auto_explain.log_min_duration = 0; configure auto_explain.log_nested_statements = ON; SET auto_explain.log_analyze = true; Estou ficando abaixo da mensagem no arquivo de log, '2014-12-08 18:21:59 IST LOG: não foi possível receber dados do cliente: nenhuma conexão pôde ser estabelecida porque a máquina de destino recusou-a ativamente' alguém pode me orientar o problema real ....
skumar
Nota: Depois de executar apenas a função plpgsql, estou ficando acima da mensagem no arquivo de log.
Skype #