[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