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
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral