Re: [firebase-br] Extrema Lentidão em Consulta Firebi rd 5
Rodrigo Gomes da Silva via lista <[email protected]> Sun, 18 May 2025 10:50:39 -0300
| Newsgroups | gmane.comp.db.firebase.portuguese |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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>> [email protected]> 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 ______________________________________________ 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