[firebase-br] Extrema Lentidão em Consulta Firebird 5

Rodrigo Gomes da Silva rodrgomes em gmail.com
Domingo Maio 18 10:50:39 -03 2025


Isso não é um problema no firebird, e o prb não é os 2 left join... no seu caso é que o 2o join que le toda tabela pra dar o sum, é executado toda vez q corre um registro de estoque, para depois agrupar... 
Por exemplo , digamos que estoque tem 100.000 registros, de 1000 materiais. Para cada 1 dos 100.000 registros ele faz a soma de um material, por 100.000 vezes ao inves de fazer somente pra 1000 que seria 1 pra cada material.

Não é um erro, pois é como ele funciona, e não esta errado, pode ser evitado melhorando o sql. O postgresql faz otimizações diferentes e por isso fica rapido, mas isso é questão da engine totalmente diferente.

O ticket que você mostrou deixa claro isso... o cara que colocou o link la referencia a um ticket que ta marcado como "type: improvement" (não bug) e vai ser recurso novo do firebird 6 que deve sair em 2026

On Sat, May 17, 2025 at 8:29 AM Luciano franca via lista <lista em firebase.com.br> wrote:

>  Ótimo comando SQL de fato ele resolve meu problema e fico muito grato.
> porém conforme pode ver nesse post existe um problema no Firebird que está no Rodmap da versão 6 para ser corrigido
> https://github.com/FirebirdSQL/firebird/issues/8568





>     Em sexta-feira, 16 de maio de 2025 às 10:34:06 BRT, Rogério <rbleonel em yahoo.com.br> escreveu: 


>  A lentidão da sua SELECT pode ser causada por alguns fatores combinados,
> especialmente relacionados ao uso incorreto ou ineficiente de JOINs com agregações (SUM, AVG).
> Join duplicado e efeito de cartesian join não intencional. Você está fazendo
> dois LEFT JOINs na mesma tabela (ESTOQUE), mas com aliases diferentes (E e
> E2), ambos ligados a CADASTRO_MERCADORIAS.
> left Join ESTOQUE E  ON (E.Cod_Mercadoria  = CM.codigo)left Join ESTOQUE E2 ON (E2.Cod_Mercadoria = CM.Codigo)
> Isso causa uma multiplicação do número de linhas retornadas antes da agregação (GROUP BY), pois:
> Se para uma mercadoria há 10 registros na tabela ESTOQUE, o primeiro join (E) retorna 10.
> O segundo join (E2) repete isso, resultando em 10 x 10 = 100 linhas, afetando
> os valores de SUM e AVG, e deixando a consulta absurdamente lenta.
> A melhor forma de resolver isso é fazer as agregações separadamente e depois unir o resultado via JOIN:
> WITH SaldoEstoque AS (  SELECT Cod_Mercadoria, SUM(quant) AS Saldo  FROM
> ESTOQUE  GROUP BY Cod_Mercadoria),PrecoEstoque AS (  SELECT Cod_Mercadoria,
> AVG(preco_custo) AS Preco  FROM ESTOQUE  GROUP BY Cod_Mercadoria)
> SELECT  CM.Codigo,  CM.MERCADORIA,  SE.Saldo,  PE.PrecoFROM
> CADASTRO_MERCADORIAS CMLEFT JOIN SaldoEstoque SE ON SE.Cod_Mercadoria =
> CM.CodigoLEFT JOIN PrecoEstoque PE ON PE.Cod_Mercadoria = CM.Codigo



> Conectado 16/05/2025 10:19:24, Luciano franca via lista <lista em firebase.com.br> escreveu:
>  para conhecimento dos amigo esse meu Post é de fato uma limitação do Firebird

> veja meu post 
> https://github.com/FirebirdSQL/firebird/issues/8568
> Extremely slow to do "Left Join" on the same table · Issue #8568 · FirebirdSQL/firebird

> |
> |
> |
> | | |

>  |

>  |
> |
> | |
> Extremely slow to do "Left Join" on the same table · Issue #8568 · Fireb...

> This command below takes 40 minutes SELECT CM.Codigo, CM.MERCADORIA,
> Sum(E.quant) As Saldo, AVG(E2.preco_custo) ...
>  |

>  |

>  |




>  Em quinta-feira, 15 de maio de 2025 às 11:32:54 BRT, Luciano franca via lista escreveu:

>  Sim eu sei disso mais veja esse Select simples que postei, e como disse faz
> 3 anos que tenho esse problema e já tentei de tudo e não consigo otimizar,  
> basta usar dois "LEFT JOIN" na mesma tabela para o Firebird ficar horrível,  
> testei Postgres, MySQL e SQLServer e todos são rápidos

> Acho que isso seja um bug no otimizador do Firebird  se puder baixar o banco
> que postei no link e ver você mesmo são apenas 2 tabelas faça o teste para ver
> https://mega.nz/file/k6gUhBpJ#4gXE7oLSW_DJdKB9UZaMUQvsI9GOPiYYJ8wqciHUVdw



>     Em quinta-feira, 15 de maio de 2025 às 11:17:06 BRT, Carlos H. Cantu via lista escreveu: 

 Lfvl>> sim são muitos registros,  banco do cliente tem mais 5 GB de tamanho, 
Lfvl>> esse é o motivo que quando o cliente reclama eu tenho que trocar o
Lfvl>> Firebird por Postgres  sempre depois de uns 4 gb o Firebird não aguenta

> Tenho bancos com dezenas de gigabytes, e há bancos por aí com centenas de GB (e
> até terabytes). O problema não deve ser o Firebird, mas o SQL que vc está
> usando.

> Cada SGBD tem seu próprio otimizador. É preciso entender os conceitos e
> limitações deles para escrever selects otimizados extraindo todo o potencial.

> []s
> Carlos H. Cantu
> eBook Guia de Migração para o FB 5 - www.firebase.com.br/guiafb5.php
> www.FireBase.com.br - www.firebirdnews.org - blog.firebase.com.br

Lfvl>>  não posso fazer "Select" usando a tabela Estoque no "From"  como Principal tem que ser o "Cadastro" 

Lfvl>> Primeiro "Cadastro"  porque pode ter produto que não tem estoque e eu
Lfvl>> preciso que esses produtos sejam mostrados,

Lfvl>> sim são muitos registros,  banco do cliente tem mais 5 GB de tamanho, 
Lfvl>> esse é o motivo que quando o cliente reclama eu tenho que trocar o
Lfvl>> Firebird por Postgres  sempre depois de uns 4 gb o Firebird não aguenta
Lfvl>>    Em quinta-feira, 15 de maio de 2025 às 10:54:34 BRT, edenilso.mga---
Lfvl>> via lista escreveu: 
Lfvl>> 
Lfvl>>  Bom dia Amigo,

Lfvl>> Fiz a restauração do seu backup aqui,

Lfvl>> na tabela ESTOQUE criei um índice para o campo Cod_Mercadoria, já melhorou,

Lfvl>> mas seu select com left na mesma tabela 2x está retornando milhões de
Lfvl>> registros.

Lfvl>> Invertendo as tabelas rodou instantaneamente ...

Lfvl>>  SELECT CM.Codigo, CM.MERCADORIA
Lfvl>>     FROM estoque e
Lfvl>>     left Join cadastro_mercadorias cm
Lfvl>>       ON (E.Cod_Mercadoria = CM.codigo)
Lfvl>>     left Join cadastro_mercadorias cm2
Lfvl>>       ON (E.Cod_Mercadoria = CM2.Codigo )

Lfvl>> Dá uma revisado no seu select.

Lfvl>> Abraço



Lfvl>> Em qui., 15 de mai. de 2025 às 10:31, Luciano franca via lista <
Lfvl>> lista em firebase.com.br> escreveu:

>>>  Tanto o Backup do Banco como os comando DDL do banco estão no link abaixo:
>>>
>>> https://mega.nz/file/k6gUhBpJ#4gXE7oLSW_DJdKB9UZaMUQvsI9GOPiYYJ8wqciHUVdw
>>>
>>>
>>>
>>>    Em quinta-feira, 15 de maio de 2025 às 10:22:59 BRT,
>>> mauricio.zottis--- via lista escreveu:
>>>
>>>  Bom dia.
>>> Poste a estrutura d(DDL) dessas tabelas
>>>
>>> Em 15/05/2025 10:11, Luciano franca via lista escreveu:
>>>
>>> > novo link permanente no Mega
>>> >
>>> https://mega.nz/file/k6gUhBpJ#4gXE7oLSW_DJdKB9UZaMUQvsI9GOPiYYJ8wqciHUVdw
>>> >
>>> > Esse problema eu já tenho a mais de 3 anos e nunca consegui resolver a
>>> > minha solução atualmente é muito complexa pois envolve eu colocar o
>>> > Postges nos cliente que reclamam de lentidão  eu não gosto do Postgres
>>> > só coloco ele em ultimo caso.
>>> > Eu continuo achando que se trata de um Bug no Firebird
>>> > Se puder dar uma analisada nesse banco só tem duas tabelas com o
>>> > simples select abaixo
>>> > SELECT CM.Codigo, CM.MERCADORIA FROM CADASTRO_MERCADORIAS CM left Join
>>> > ESTOQUE E ON (E.Cod_Mercadoria = CM.codigo) left Join ESTOQUE E2 ON (
>>> > E2.Cod_Mercadoria = CM.Codigo ) Group By 1, 2
>>> >
>>> > Em quinta-feira, 15 de maio de 2025 às 09:59:10 BRT, Luciano franca via
>>> > lista escreveu:
>>> >
>>> > Eu não entendi o que você quiz dizer com  "+0 ou || "
>>> > veja esse link onde tem o backup do Banco feito em Firebird 3  e também
>>> > os comandos SQL caso quero criar o banco já com os
>>> > Dadoshttps://
>>> mega.nz/file/8uYwiBoK#y3PdspfXLOSc6wGS1c4i6vHFHCXAzgqfAvX_rY2ZGMM
>>> > Esse problema eu já tenho a mais de 3 anos e nunca consegui resolver a
>>> > minha solução atualmente é muito complexa pois envolve eu colocar o
>>> > Postges nos cliente que reclamam de lentidão  eu não gosto do Postgres
>>> > só coloco ele em ultimo caso.
>>> > Eu continuo achando que se trata de um Bug no Firebird
>>> > Se puder dar uma analisada nesse banco só tem duas tabelas com o
>>> > simples select abaixo
>>> > SELECT CM.Codigo, CM.MERCADORIA FROM CADASTRO_MERCADORIAS CM left Join
>>> > ESTOQUE E ON (E.Cod_Mercadoria = CM.codigo) left Join ESTOQUE E2 ON (
>>> > E2.Cod_Mercadoria = CM.Codigo ) Group By 1, 2
>>> >
>>> > Em quinta-feira, 15 de maio de 2025 às 09:41:34 BRT, Carlos H. Cantu
>>> > via lista escreveu:
>>> >
>>> > Com LEFT é a mesma coisa, PLAN e tempo continuam bons:
>>> >
>>> > Query
>>> > ------------------------------------------------
>>> > select emissao, pn.codprod , pn2.codprod
>>> > from notas n
>>> > left join prodnota pn on pn.id_num = n.id_num
>>> > left join prodnota pn2 on pn2.id_num = n.id_num
>>> > where n.emissao > date '1.10.2024'
>>> >
>>> > Plan
>>> > ------------------------------------------------
>>> > PLAN JOIN (JOIN (N INDEX (IDX_VENDAS_EMISSAO), PN INDEX
>>> > (FK_PRODNOTA_NOTAFISCAL)), PN2 INDEX (FK_PRODNOTA_NOTAFISCAL))
>>> >
>>> > Query Time
>>> > ------------------------------------------------
>>> > Prepare      : 0,00 ms
>>> > Execute      : 141,00 ms
>>> > Avg fetch time: 0,01 ms
>>> >
>>> > []s
>>> > Carlos H. Cantu
>>> > eBook Guia de Migração para o FB 5 - www.firebase.com.br/guiafb5.php
>>> > [1]
>>> > www.FireBase.com.br [2] - www.firebirdnews.org [3] -
>>> > blog.firebase.com.br
>>> >
>>> > Lf>  O colega não usou "LEFT" não posso usar "INNER" eu não entendi o
>>> > que você quiz dizer com  "+0 ou || "
>>> >
>>> > Lf> veja esse link onde tem o backup do Banco feito em Firebird 3  e
>>> > também os
>>> > Lf> comandos SQL caso quero criar o banco já com os Dados
>>> > Lf> 6.5 MB file on MEGA
>>> >
>>> > Lf> Esse problema eu já tenho a mais de 3 anos e nunca consegui
>>> > resolver a
>>> > Lf> minha solução atualmente é muito complexa pois envolve eu colocar o
>>> > Postges
>>> > Lf> nos cliente que reclamam de lentidão  eu não gosto do Postgres só
>>> > coloco ele em ultimo caso.
>>> >
>>> > Lf> Eu continuo achando que se trata de um Bug no Firebird
>>> >
>>> > Lf> Se puder dar uma analisada nesse banco só tem duas tabelas com o
>>> > simples select abaixo
>>> >
>>> > Lf>  SELECT CM.Codigo, CM.MERCADORIA FROM CADASTRO_MERCADORIAS CM left
>>> > Join
>>> > Lf> ESTOQUE E ON (E.Cod_Mercadoria = CM.codigo) left Join ESTOQUE E2 ON
>>> > (
>>> > Lf> E2.Cod_Mercadoria = CM.Codigo ) Group By 1, 2
>>> >
>>> > Lf> |
>>> > Lf> |
>>> > Lf> |
>>> > Lf> |  |  |
>>> >
>>> > Lf>  |
>>> >
>>> > Lf>  |
>>> > Lf> |
>>> > Lf> |  |
>>> > Lf> 6.5 MB file on MEGA
>>> >
>>> > Lf>  |
>>> >
>>> > Lf>  |
>>> >
>>> > Lf>  |
>>> >
>>> > Lf>    Em quinta-feira, 15 de maio de 2025 às 08:54:50 BRT, Carlos H.
>>> > Cantu escreveu:
>>> > Lf>
>>> > Lf>  O fato de mencionar a mesma tabela em mais de um join, por si só,
>>> > não é o
>>> > Lf> problema, desde que o PLAN mostre que um índice apropriado está
>>> > sendo usado em
>>> > Lf> ambas as buscas.
>>> >
>>> > Lf> No seu caso, ao tirar o segundo join, provavelmente está fazendo
>>> > com que o PLAN
>>> > Lf> mude e fique mais eficiente. Vc vai ter que ir testando alterando
>>> > as ordens dos
>>> > Lf> joins, usando +0 ou || '' em algumas junções, para tentar fazer com
>>> > que o
>>> > Lf> Firebird escolha um plano mais eficiente.
>>> >
>>> > Lf> Veja abaixo, o tempo foi muito rapido mesmo com 2 joins na mesma
>>> > tabela. O PLAN
>>> > Lf> está eficiente:
>>> >
>>> > Lf> Query
>>> > Lf> ------------------------------------------------
>>> > Lf> select emissao, pn.codprod, pn2.codprod
>>> > Lf> from notas n
>>> > Lf> join prodnota pn on pn.id_num = n.id_num
>>> > Lf> join prodnota pn2 on pn2.id_num = n.id_num -- Repetindo o JOIN
>>> > where n.emissao >> date '1.10.2024'
>>> >
>>> > Lf> Plan
>>> > Lf> ------------------------------------------------
>>> > Lf> PLAN JOIN (N INDEX (IDX_VENDAS_EMISSAO), PN INDEX
>>> > (FK_PRODNOTA_NOTAFISCAL), PN2 INDEX (FK_PRODNOTA_NOTAFISCAL))
>>> >
>>> > Lf> Query Time
>>> > Lf> ------------------------------------------------
>>> > Lf> Prepare      : 0,00 ms
>>> > Lf> Execute      : 187,00 ms
>>> > Lf> Avg fetch time: 0,02 ms
>>> >
>>> > Lf> Query
>>> > Lf> ------------------------------------------------
>>> > Lf> select emissao, pn.codprod
>>> > Lf> from notas n
>>> > Lf> join prodnota pn on pn.id_num = n.id_num -- APENAS 1 JOIN
>>> > where n.emissao >> date '1.10.2024'
>>> >
>>> > Lf> Plan
>>> > Lf> ------------------------------------------------
>>> > Lf> PLAN JOIN (N INDEX (IDX_VENDAS_EMISSAO), PN INDEX
>>> > (FK_PRODNOTA_NOTAFISCAL))
>>> >
>>> > Lf> Query Time
>>> > Lf> ------------------------------------------------
>>> > Lf> Prepare      : 0,00 ms
>>> > Lf> Execute      : 62,00 ms
>>> > Lf> Avg fetch time: 0,01 ms
>>> >
>>> > Lf> []s
>>> > Lf> Carlos H. Cantu
>>> > Lf> eBook Guia de Migração para o FB 5 -
>>> > www.firebase.com.br/guiafb5.php [1]
>>> > Lf> www.FireBase.com.br [2] - www.firebirdnews.org [3] -
>>> > blog.firebase.com.br
>>> >
>>> > Lfvl>>  não pode ser "INNER" tem que ser "LEFT"  eu coloquei 2 no caso
>>> > mais
>>> > Lfvl>> simples porém tem alguns caso onde tenho até 4 "JOINS" na mesma
>>> > tabela o
>>> > Lfvl>> problema é que isso no Postgres roda em segundos como coloquei
>>> > no 1 email
>>> > Lfvl>> 15 segundos contra 30 minutos do Firebird
>>> >
>>> > Lfvl>> Eu estou achando que isso é um bug no Firebird.
>>> > Lfvl>>    Em quinta-feira, 15 de maio de 2025 às 08:19:17 BRT, Armando
>>> > Boza
>>> > Lfvl>> Gonçalves via lista escreveu:
>>> > Lfvl>>
>>> > Lfvl>>  Bom dia, 2 LEFT JOIN para a mesma tabela?
>>> >
>>> > Lfvl>> Eu já tive problemas de desempenho com left join e acabei
>>> > resolvendo com
>>> > Lfvl>> UNION, separei os selects e ficou bem rápido.
>>> >
>>> > Lfvl>> Faz um teste.
>>> >
>>> > Lfvl>> Em 15/05/2025 07:09, Luciano franca via lista escreveu:
>>> > Acredito que encontrei o problema e não sei como resolver mesmo sem CTE
>>> > não adianta
>>> > basta acessar a mesma tabela duas vezes para o Firebird se perder
>>> > se fizer algo simples como isso já vai dar problemas veja
>>> >
>>> > Select
>>> > Cp.codigo, Cp.nome
>>> > From cadastro_pessoas cp
>>> > left join venda v on (v.cod_cliente = cp.codigo) Left join venda v2 on
>>> > (v2.cod_cliente = cp.codigo)  se eu comentar essa segunda junção é
>>> > excecutado em 1 segundo
>>> > Group by 1, 2
>>>


> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para saber como gerenciar/excluir seu cadastro na lista, use:
> http://www.firebase.com.br/fb/artigo.php?id=1107
> Para consultar mensagens antigas: http://www.firebase.com.br/pesquisa_lista.html
>  
> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para saber como gerenciar/excluir seu cadastro na lista, use:
> http://www.firebase.com.br/fb/artigo.php?id=1107
> Para consultar mensagens antigas: http://www.firebase.com.br/pesquisa_lista.html

> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para saber como gerenciar/excluir seu cadastro na lista, use:
> http://www.firebase.com.br/fb/artigo.php?id=1107
> Para consultar mensagens antigas: http://www.firebase.com.br/pesquisa_lista.html


> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para saber como gerenciar/excluir seu cadastro na lista, use:
> http://www.firebase.com.br/fb/artigo.php?id=1107
> Para consultar mensagens antigas: http://www.firebase.com.br/pesquisa_lista.html




Mais detalhes sobre a lista de discussão lista