[firebase-br] Performance Inclusão Massa x Trigger x Tabelas

Gladiston Santana gladiston em vidy.com.br
Sex Nov 30 16:03:57 -03 2012


Para fazer uma importação como a que você diz, deve-se desativar as
triggers e então fazer as inclusões que deseja. Se houver algum calculo
para fazer, executa-se isso no final da importação com os registros que
foram importados.
Triggers foram feitas para serem usados no momento de interatividade com o
programa/usuario, um bulkcopy com as triggers ativadas é penoso mesmo.
Outra coisa que se pode fazer é alterar seu sistema para que a
inclusão/alteração/exclusão chame uma SP que faça todas as operações
possiveis, nesse caso voce pode aproveitar a mesma SP no seu programa de
importação de dados, ao inves do insert, use execute procedure.


Gladiston Santana
Departamento de TI
Grupo Vidy
Tel (11) 4787-3122 ramal 228
Rod. Régis Bittencourt 3360 - Km 272,5
Taboão da Serra - SP - CEP: 06793-000
Visite nosso site: www.vidy.com.br
Visite também : www.expolabor.com.br





Em 30 de novembro de 2012 13:06, Valdemir (gmail)
<valdemirjs em gmail.com>escreveu:

> Boa tarde dia pessoal
>
> Aqui uso
> Delphi 2010 / IBO4 e Firebird 2.1
>
> Tenho as seguintes tabelas
>
> Pagamento Titualos
> Livro Caixa
> Cheques
> Banco
> MovCarcao
>
> Um pagamento de titulo, pode ser feito, atraves de cartão, ou atraves de
> deposito/boleto, ou ataves de dinheiro/cheque que ai entraria no caixa, e
> um cheque pode ser usado para pagamento mais de um titulo, e se o cheque
> voltar então aquele titulo fica “marcado” para o usuario saber de onde veio
> aquele cheque
> Existe também a possibilidade de inclusão, ou alteração de valores, ou até
> mesmo um titulo que foi pago em banco, por um erro do usuario, pode na
> verdade foi pago em dinheiro, e ai no caso o usuario irá alterar o
> pagamento do titulo.
>
> Na trigger after insert x update x before delete, faço todas as
> checkagens, dou insert update ou delete nas tableas relacionadas, ou seja
> tudo na trigger da tabela “pagamento de titulos”. até ai ok, durante a
> digitação a performance é aceitavel o usuario não percebe lentidão.
>
> Agora estou montando uma importação em massa, leio o arquivo e gero um
> script INSERT INTO, e notei que o tempo para inclusão estava muito lento...
> fiz alguns testes mudando a qtde de registros para dar commit, mesmo assim
> não tive um bom resultado
>
> Melhorei a performance da trigger, reescrevendo selects e inserts e
> updates para melhorar, também não foi o suficiente
>
> Ai então parti para a ignorancia .. rs, tenho um lote de 500 registros, o
> tempo para importalos com a trigger ligada leva em torno de 35/40 segundos,
> peguei a trigger e desliguei ela, o tempo caiu para menos de 1 segundo os
> mesmos 500 registros.
>
> Com isso descobri é pau na trigger, comentei a trigger inteira e fui
> descomentando ela aos poucos e constatei que realmente era problema na
> trigger.
>
> O que eu fiz, como na importação tenho todas as informações, não é
> necessário passar pela trigger, então fiz o seguinte, criei uma variavel de
> contexto, e atribui um valor nela, e no inicio da trigger fiz o seguinte
>
> IF (UPPER(COALESCE(RDB$GET_CONTEXT('USER_SESSION','SINCRONIZANDO'),'NÃO'))
> = 'SIM') THEN
>   EXIT;
>
> Pensei agora vai ficar rapido, mandei rodar melhorou o tempo entre 22/27
> segundos, mas nada perto do que era antes, bom achei que era problema com a
> minha variavem então peguei e coloquei um exit sem nenhum if e coloquei uma
> msg de expetion para ter certeza que não estava passando pela trigger
>
>   EXIT;
>   exception except_geral 'teste';
>
> estas eram as duas primeiras linhas da trigger, o tempo não se alterou
> ficou entre 22/27 segundos, enfim tava ficando já meio careca com o
> problema, poruqe não passou pela trigger inteira, pq não deu o exception,
> mas mesmo assim o tempo continuou alto, ai então comentei todos os lugares
> de davam select, update insert ou delete em outras tabelas, e mandei
> rodar...
>
> Adivinhem o tempo caiu para incluir os 500 registros, menos de 400
> milesimos de segundo...
>
> achei o problema rs, testei desativando a trigger, e novamente o tempo foi
> otimo 392 milesimos de segundo para 500 registros, eu como desenvolvedor
> fiquei puto, afinal não esta passando pelo codigo não deveria demorar tanto
> assim, bom fiz o seguinte, criei uma procedure para dar um insert update e
> delete, e ai tirei da trigger o insert update e delete, e chamei a função
> com o comando EXECUTE PROCEDURE, mesma coisa voltou para 22/27 segundos
>
> da a entender, que o otmizador do firebird, mesmo não usando o comando na
> determinada tabela, ele meio que carrega as tabelas dependentes da trigger
> e ai acaba deixando a trigger lenta mesmo se o codigo dela não for
> executado.
>
> É isso mesmo ?
> Este é um corportamento padrão do firebird ?, em versoes superiores o
> mesmo ocorre ?
> Existe como mudar isso com algum parametro ? semelhante quando fornecemos
> o plano para um select ?
>
> Eu para resolver simplesmente vou desativar as triggers como até já tinha
> visto sobre o assunto nas pesquisas que eu fiz, mas eu jurava que como já
> tinha feito uma condição para não passar na trigger quando estiver
> importando, não seria necessário desativar as triggers.
>
>
>
>
>
> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para saber como gerenciar/excluir seu cadastro na lista, use:
> http://www.firebase.com.br/fb/artigo.php?id=1107
> Para consultar mensagens antigas: http://firebase.com.br/pesquisa



Mais detalhes sobre a lista de discussão lista