[firebase-br] RES: Problemas Lentidão em base Firebird/Contato Carlos Cantu

Eurides Baptistella eurides.baptistella em gmail.com
Ter Ago 23 17:20:15 -03 2011


Então amigos, segue um pequeno detalhamento:
O ERP que a empresa possui permite integrar os lançamentos de documentos
(cheques,boletos,etc) com o caixa (com outras contas também, conforme a
configuração utilizada pelo cliente) de forma automática ou manual. Assim,
se o cliente

desejar, poderá integrar os documentos de um mês inteiro (na opção manual),
e caso ele tenha seus 20 mil documentos lançados durante o período esses
serão integrados de uma só vez.

Partindo para a estrutura, temos o seguinte:
 - Tabela DOCUMENTOS - Armazena os documentos, valores, portador.... etc
 - Tabela RASTREAMENTO - Identifica de onde o registro veio e para onde vai
após a integração
 - Tabela CAIXA - Armazena os lançamentos feitos para a conta Caixa por
exemplo (valores, portador... etc)
 - Tabela TOTALIZADORA - Contem valores totalizados por lotes de documentos
por exemplo.

Assim, quando executo uma procedure pcd_exclui_lancamentos(empresa,
data_ini, data_fin) ele executará a seguinte rotina:
 1- for select na tabela DOCUMENTOS com base nos parâmentros informados;
 2- Exclui lançamentos da tabela CAIXA;
   2.1 Essa por sua vez executa uma trigger no after delete que atualiza os
valores na tabela TOTALIZADORA;
      - update TOTALIZADORA set valor_total = valor_total - valor_excluido
where chave = :OLD.chave; por exemplo
 3- Atualiza o registro de RASTREAMENTO.


procedure pcd_exclui_lancamentos
  FOR SELECT EDT, LTE, LCT
        FROM DOCUMENTOS
       WHERE ((:pEmp = ',0,') or (:pEmp Containing SubString(','||EOR||','
from 1 for 5)))
         and DTC between :pDtaIni and :pDtaFin and ITG='S'
        INTO :iEdc, :iLte, :iLcc
  DO BEGIN

    if (iEdc is null) then iEdc = 0;
    if (iLte is null) then iLte = 0;
    if (iLcc is null) then iLcc = 0;

      /* EXCLUI OS LANÇAMENTOS DO CAIXA */
    DELETE FROM CAIXA /* aqui dispara a trigger */
     WHERE Emp = :iEdc and Lte = :iLte and Cod = :iLcc;

  END

  /*  ATUALIZA REGISTROS DA TABELA DE RASTREAMENTO PARA INTEGRAR
MANUALMENTE  */
  UPDATE RASTREAMENTO SET LCT = 0, PIT = 'N', ITG = 'N' , FIT = 'M'
   WHERE ((:pEmp = ',0,') or (:pEmp Containing SubString(','||EOR||',' from
1 for 5)))
     and DTC between :pDtaIni and :pDtaFin and ITG='S';

trigger da tabela CAIXA
  if (OLD.CTD>0) then OldDbt = OLD.VLR;
  else                OldDbt = 0;
  if (OLD.CTC>0) then OldCdt = OLD.VLR;
  else                OldCdt = 0;

  update TOTALIZADORA
     set TLC = TLC - 1
       , TVC = TVC - OLD.VLR
       , TDC = TDC - :OldDbt
       , TCC = TCC - :OldCdt
       , DTM = 'today'
       , USR = 0
   where EMP = OLD.EMP
     and COD = OLD.LTE;


O processo em teoria é simples, detalhe importante é que quando eu removo o
passo 2.1 e trago o update para dentro da procedure o banco trabalha
normalmente, não há lentidão. Já quando é executado pela trigger no decorrer
do tempo começa

a ficar lento.
O mais intrigante é que esse mesmo processo rodando com os mesmos dados em
base Postgres se comporta muito bem.

As tabelas estão indexadas de forma correta e o melhor, utilizando os
indices.

Segue abaixo mais informações do plan etc ...

Primeira Execução (Rápida)
Query
------------------------------------------------
execute procedure pcd_int_exclui_crcctb(',2,','31.05.2011','31.05.2011');


Query Time
------------------------------------------------
Prepare       : 1.825,00 ms
Execute       : 6.567,00 ms
Avg fetch time: 0,00 ms

Memory
------------------------------------------------
Current: 30.957.672
Max    : 31.086.744
Buffers: 3.000

Operations
------------------------------------------------
Read   : 518
Writes : 907
Fetches: 229.871


Enchanced Info:
+--------------------------+-----------+-----------+-------------+---------+---------+---------+
|        Table Name        |  Records  |  Indexed  | Non-Indexed | Updates |
Deletes | Inserts |
|                          |   Total   |   reads   |    reads    |
|         |         |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+
|                 DOCUMENTO|     11926 |      3880 |           0 |    1940
|       0 |       0 |
|                     CAIXA|      8569 |      1940 |           0 |       0
|    1940 |       0 |
|              TOTALIZADORA|      1869 |      1940 |           0 |    1940
|       0 |       0 |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+

Segunda Execução (Processo com problemas e lento)
Query
------------------------------------------------
execute procedure pcd_int_exclui_crcctb(',2,','31.05.2011','31.05.2011');


Query Time
------------------------------------------------
Prepare       : 16,00 ms
Execute       : 1.242.033,00 ms
Avg fetch time: 0,00 ms

Memory
------------------------------------------------
Current: 30.941.128
Max    : 32.137.560
Buffers: 3.000

Operations
------------------------------------------------
Read   : 435
Writes : 35
Fetches: 417.472.608


Enchanced Info:
+--------------------------+-----------+-----------+-------------+---------+---------+---------+
|        Table Name        |  Records  |  Indexed  | Non-Indexed | Updates |
Deletes | Inserts |
|                          |   Total   |   reads   |    reads    |
|         |         |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+
|                DOCUMENTOS|     11926 |      3880 |           0 |    1940
|       0 |       0 |
|                     CAIXA|      8569 |      1940 |           0 |       0
|    1940 |       0 |
|              TOTALIZADORA|      1869 |      1940 |           0 |    1940
|       0 |       0 |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+



Mais detalhes sobre a lista de discussão lista