2014-02-05 Daniel Cordeiro <dmora...@gmail.com>:

>
> Em 05-02-2014 11:55, Matheus de Oliveira escreveu:
>  ...
>
> ', uma vez que a view vai gerar todos os dados e só depois é que o
> planejador realizará a restrição através do cláusula
>
>

> WHERE e ordenações necessárias.
>
>>
>>
>  humm... Sua afirmação não está correta. [...]
> Eu até diria que nesse exemplo específico a view me parece até mais
> adequada e mais fácil de manter do que a função.
>
>    Como eu falei no email que respondi para Euler: My bad :-(
>

Tranquilo, acontece. Só corrigi para não deixar erros assim no histórico...
:-)


>
>>  Minha sugestão é criar uma função que realiza a consulta já adicionando
>> as restrições necessárias para a triagem inicial dos dados desejados.
>> [...]
>>
>> Eu só recomendaria, nesse caso especificamente, a usar uma função SQL ao
>> invés de PL/pgSQL:
>>
>>     CREATE OR REPLACE FUNCTION sp_lancamentos(IN CODCONTA varchar)
>>     RETURNS TABLE(i int, c1 text,c2 text, c text)
>>     AS $$
>>         SELECT id,conta,campo1,campo2 FROM lancamentos WHERE conta =
>> CODCONTA;
>>     $$
>>     LANGUAGE SQL;
>>
>>  Para chamá-la:
>
>      SELECT * FROM sp_lancamentos('Produtivo');
>
>  (a chamada em si seria igual à PL/pgSQL, só quis exemplificar)]
>
> Claro, usei o plpgsql por me basear em algo que já tinha, e o mesmo
> depende dos recursos além da sql.
>
>

Ah sim, entendo muito bem. Só quis deixar claro que quando queremos
**simples**mente uma espécie de "view parametrizada" a troca natural é para
uma função em linguagem SQL. Na verdade foi mais um complemento à sua
resposta.


>
>
>>  Para uma function  muito grande e com muitas variáveis para
>> substituição, vale a pena utilizar a cláusula EXECUTE no RETURN QUERY (isso
>> já me salvou de vários problemas em functions com mais mais de 1500 linhas
>> e código e dezenas de variáveis)* 2*:
>>
>>
>> *     ....     RETURN QUERY EXECUTE 'SELECT id,conta,campo1,campo2 FROM
>> lancamentos WHERE conta = $1' USING CODCONTA;*
>>     ....
>>
>>
>>
>  Ah? Por quê? Eu particularmente tento evitar o EXECUTE ao menos que
> estritamente necessário. Lembre-se que ele não pode ser otimizado pelo
> PL/pgSQL para armazenar o plano de execução.
>
>    Eu também não. Mas neste meu caso, após o crescimento de dados em
> alguns clientes (alguns milhões de registros em dezenas de tabelas), o
> QueryPlan dentro da procedure passou a ser tratado de maneira totalmente
> diferente  se comparado à execução da mesma query já com os valores
> prefixados nas condicionais e subqueryes fora da procedure. Aparentemente,
> como o prepare acontece antes do conhecimento dos parâmetros na procedure,
> o planejador gerava um plano de execução mais custoso. (novamente, esta foi
> a minha impressão sobre o caso).
>
> Estou falando da mesma consulta rodando em 5 horas dentro da procedure e 7
> segundos rodando fora. Inicialmente pensei que fosse a adoção do RETURN
> QUERY. Ao modificar a procedure fazendo o retorno com o EXECUTE, o tempo
> foi normalizado e o custo de operação dentro e fora da procedure ficou, de
> fato, irrelevante.
>
>
Sim, isso realmente poderia acontecer. Creio que o seu caso foi numa versão
anterior à 9.2, correto?

Na 9.2 o modelo de gerar plano de execução para "prepared statements"
mudou, e ficou bem melhor. Agora o plano é gerado no EXECUTE, quando já são
conhecidos os valores. Recomendo você a testar novamente essas funções numa
versão mais recente (9.2 ou 9.3) e verificar se o comportamento ainda é o
mesmo. Se o fizer, por favor compartilhe os resultados com os colegas,
;-)...


>
>
>
>>  Lembrando que estas ações podem dificultar a análise de um problema
>> futuro, pois o EXPLAIN não vai detalhar o conteúdo interno executado na
>> função e nem nos logs.
>>
>>
>  +1. Otimizar funções é uma tarefa bem árdua. Só uma dica, a extensão
> auto_explain pode ajudar nessa tarefa. ;-)
>
>
> Obrigado pela dica! Vou estudar a extensão para verificar sua adoção em
> nosso ambiente.
>
>
É, na minha opinião, um pré-requisito para quem usa muitas funções.

Atenciosamente,
-- 
Matheus de Oliveira
Analista de Banco de Dados
Dextra Sistemas - MPS.Br nível F!
www.dextra.com.br/postgres
_______________________________________________
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Reply via email to