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

Valdemir (gmail) valdemirjs em gmail.com
Sex Nov 30 13:06:39 -03 2012


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.








Mais detalhes sobre a lista de discussão lista