[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