From: [email protected]
Date: Mon, 10 Feb 2014 19:04:11 -0200
To: [email protected]
Subject: Re: [pgbr-geral]       Diferenças de performance rodando funcao


2014-02-07 12:57 GMT-02:00 Fabio Barros <[email protected]>:
>
> Boa tarde pessoal!
>
> Estou tentando entender a diferença de performance em duas implementações que 
> fazem a mesma coisa, mas ainda não consegui achar uma explicação.


>
> Segue abaixo os dois exemplos, caso alguém possa me ajudar no entendimento:
>
> Tenho um arquivo texto de 12 mil linhas, parte do conteudo abaixo:
>
> SELECT aux_ir_gao_generico ('I', 39700, '1621', '39700', 0);


> SELECT aux_ir_gao_generico ('I', 39700, '1622', '39700', 0);
> . . .
> SELECT aux_ir_gao_generico ('I', 39700, '1623', '39700', 0);
> SELECT aux_ir_gao_generico ('I', 39700, '1624', '39700', 0);


>
> ******* Fiz um programa C++ que simplesmente lê o arquivo e executa cada uma 
> de suas linhas, a seguir:
> [...]
>   fseek (a_arq_executado, 0, SEEK_SET);
>

Não tem necessidade desse fseek aqui, mas acho que não faz mal também...


 
>
>   for(int cont_linha = 1; (fgets(l_comando_sql, sizeof(l_comando_sql), 
> a_arq_executado) != NULL); cont_linha++){
>     l_result = PQexec(l_conexao, l_comando_sql); -- comentando esta linha, 
> fica instantaneo (nao é problema ao ler o arquivo)


>   }
>
> [...]
>
> ******* No outro teste, fiz uma funcao postgres e 'embuti' as mesmas queries, 
> a seguir:
>
> CREATE FUNCTION insere_gao_mult () RETURNS INTEGER AS'


> DECLARE
>   l_retorno INT;
> BEGIN
>
> SELECT into l_retorno aux_ir_gao_generico (''I'', 39700, ''1621'', ''39700'', 
> 0);
> SELECT into l_retorno aux_ir_gao_generico (''I'', 39700, ''1622'', ''39700'', 
> 0);


> -- omitindo as outras linhas, só 12 mil dentro de uma funcao... rs
> SELECT into l_retorno aux_ir_gao_generico (''I'', 39700, ''1623'', ''39700'', 
> 0);
> SELECT into l_retorno aux_ir_gao_generico (''I'', 39700, ''1624'', ''39700'', 
> 0);


>
> [...]
> Tempo do programa C++..................................: 1 minuto
> Tempo executando a funcao q contem as linhas do arquivo: 3 segundos
>
> Particularmente, acho muito interessante este tipo de dúvida, e por isso 
> resolvi postar aqui....


>
> Pq toda essa diferença no tempo?!?!?! (desculpem a ignorância)

Bom, precisaríamos de uma análise mais detalhada para confirmar, mas o que 
percebi de mais imediato é o fato de você não trabalhar com transações no 
código em C, e uma função PL é sempre executada numa mesma transação, logo o 
tempo de início/fim de cada transação no código em C (basicamente a cada 
comando) pode pesar bastante. O mais equivalente seria:



    PQexec(l_conexao, "BEGIN;");
    for(int cont_linha = 1; (fgets(l_comando_sql, sizeof(l_comando_sql), 
a_arq_executado) != NULL); cont_linha++){

        l_result = PQexec(l_conexao, l_comando_sql);    }
    PQexec(l_conexao, "COMMIT;");



Teste essa versão e nos diga o resultado. Ah, se for colocar isso em produção, 
não se esqueça de verificar por erros na execução de cada comando, ok?

Mais uma coisa, a função em PL/pgSQL na primeira execução irá preparar os 
comandos e armazená-los em memória, assim uma execução subsequente será mais 
rápida, sem dúvidas, que a versão em C.



Se o padrão do seu arquivo é sempre chamar a função aux_ir_gao_generico, há uma 
otimização bem simples, que é preparar a consulta:

   SELECT l_retorno aux_ir_gao_generico ($1, $2, $3, $4, $5);



E depois executar passando os parâmetros.

Atenciosamente,-- 
Matheus de Oliveira
Analista de Banco de Dados
Dextra Sistemas - MPS.Br nível F!
www.dextra.com.br/postgres






Perfeito Matheus!!!
Fiz o teste com a transação e a diferença de tempo não existe mais, caiu do 1 
minuto para 3 segundos, ou seja, meu gargalo estava justamente nisso e eu não 
me 'atentei' que repeti o processo 12 mil vezes.
Obrigado pelas dicas, e quanto a verificar os erros de retorno, estou checando 
sim, só omiti do exemplo pra tentar deixar minha mensagem mais simples.
Abraços a todos!
Fabio Barros


                                          
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a