[firebase-br] SQL Trava no FB2.0 e funciona no FB1.5
Caio Oliveira
news em caiosistemas.com.br
Qui Ago 3 17:04:44 -03 2006
Olá amigos,
Ontem estava testando algumas SQLs no FB2.0 quando percebí uma delas
fazia com que o fbserver consumisse 100% de CPU (acabei interrompendo
depois de alguns minutos por que ela não completava); Porêm achei
estranho que essa mesma SQL no FB1.5 executava normalmente.
Fui rever essa SQL e descobri o que fazia com que ela demorasse tanto no
FB2; porêm não entendi ainda porque no FB1.5 o problema não apareçe,
visto que houveram várias implementações de recursos tanto na
seletividade dos "Índices" como no "Otimizador" do FB2; então,
teoricamente deveria funcionar melhor ou igual.
Vou procurar exemplificar no trecho abaixo como solucionei o problema
dessa SQL em questão:
SQL Original
(causa pane no FB2 - 100% CPU; porêm, resposta quase imediata
no FB1.5)
-----------------------------------------------------------------
select a.id_emp AS NUM, e.slogan AS LOJA, sum(a.nf_vtotal) AS FATURAmto,
sum((select custo from getcustonota(a.id_emp, a.nf_nota, a.nf_serie,
a.destino))) AS CUSTO from cepnt001 a
left join cepemp01 e ON (e.id_cepemp01 = a.id_emp)
where
(a.nf_data between '01.07.2006' and '31.07.2006') and
(a.operacao=0 ) and
(not a.nf_ncli in ( select tmp.codcli from cepemp01 tmp GROUP by
codcli HAVING COUNT(tmp.codcli) > 0 ))
group by 1,2
-----------------------------------------------------------------
SQL Modificada (funcionou OK também no FB2
resposta quase imediata nos dois FB (1.5 e 2.0)
-----------------------------------------------------------------------
select a.id_emp AS NUM, e.slogan AS LOJA, sum(a.nf_vtotal) AS FATURAmto,
sum((select custo from getcustonota(a.id_emp, a.nf_nota,
a.nf_serie))) AS CUSTO from cepnt001 a
left join cepemp01 e ON (e.id_cepemp01 = a.id_emp)
where
(a.nf_data between '01.07.2006' and '31.07.2006') and
(a.operacao=0 ) and
(not a.nf_ncli in ( select tmp.codcli from cepemp01 tmp GROUP by
codcli HAVING COUNT(tmp.codcli) > 0 ))
group by 1,2
------------------------------------------------------------------------
Observações: Repare que a modificação feita foi que retirei um parametro
do procedure "destino"; embora esse campo e todos os outros usados na
SQL estivessem indexados na tabela origem.
Procedure GETCUSTONOTA (antes)
------------------------------
Begin
for select sum(e.cust_rep*e.quant) from cepsa001 e
where (e.id_emp = :idemp and e.nota = :nota and e.notaserie = :serie and
e.destino = :destino)
into :custo do
Begin
IF (custo IS NULL) THEN custo = 0.00;
SUSPEND;
End
END
Procedure GETCUSTONOTA (depois)
-------------------------------
Begin
/* Verifica Ultimo Codigo Registrado */
for select sum(e.cust_rep*e.quant) from cepsa001 e
where (e.id_emp = :idemp and e.nota = :nota and e.notaserie = :serie)
into :custo do
Begin
IF (custo IS NULL) THEN custo = 0.00;
SUSPEND;
End
END
Obs.: Lembrando que a tabela CEPSA001 possui um índice para cada campo
de dados usado na SQL.
abraços!
Caio Oliveira
Mais detalhes sobre a lista de discussão lista