Re: [firebase-br] Extrema Lentidão em Consulta Firebi rd 5
Rogério via lista <[email protected]> Fri, 16 May 2025 10:35:47 -0300
| Newsgroups | gmane.comp.db.firebase.portuguese |
|---|---|
| Message-ID | <[email protected]> |
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.Preco FROM CADASTRO_MERCADORIAS CM LEFT JOIN SaldoEstoque SE ON SE.Cod_Mercadoria = CM.Codigo LEFT JOIN PrecoEstoque PE ON PE.Cod_Mercadoria = CM.Codigo Conectado 16/05/2025 10:19:24, Luciano franca via lista <lista-JZX6CTs6PlFWk0Htik3J/[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