Luiz Fernando Posted February 24, 2016 Report Share Posted February 24, 2016 Colegas veja se alguém pode dar alguma sugestão no caso abaixo o select abaixo é executado em 00:01:43 (1 minuto e 43 segundos) cSql="SELECT DATA,produto FROM " cSql+="(SELECT MAX(DATA)AS DATA,produto " cSql+=" FROM pedido " cSql+=" WHERE tipo='1' " cSql+=" GROUP BY produto " cSql+=" ORDER BY produto)sald " cSql+=" WHERE DATA<'2015-11-30'" mais no caso eu preciso tb do nome do produtio, com o select abaixo eu abandonei qdo estava nos 00:35:00( trinta e cinco minutos) cSql="SELECT data,produto,descricao" cSql+=" FROM (SELECT MAX(pe.data) AS data,pe.produto,pr.descricao" cSql+=" FROM pedido as pe, produto as pr" cSql+=" WHERE pe.tipo='1'" cSql+=" AND pe.produto = pr.codigo" cSql+=" GROUP BY pe.produto" cSql+=" ORDER BY pe.produto) sald" cSql+=" WHERE data < '2015-11-30'" Obs: o objetivo deste select é saber os produtos que não tiveram movimento depois de uma data Obrigado Ronaldbuch 1 Quote Link to comment Share on other sites More sharing options...
joaosolution Posted February 25, 2016 Report Share Posted February 25, 2016 Luiz Sugiro: cSql="SELECT sald.data,sald.produto,produto.descricao" cSql+=" FROM (SELECT MAX(pe.data) AS data,pe.produto" cSql+=" FROM pedido as pe" cSql+=" WHERE pe.tipo='1'" cSql+=" GROUP BY pe.produto" cSql+=" ORDER BY pe.produto) sald" cSql+=" LEFT JOIN produto ON produto.produto = sald.codigo" cSql+=" WHERE data < '2015-11-30'" Primeiro você faz o filtro para reduzir os resultados com Where e depois você executa a junção das tabelas com JOIN ele é mais rápido que o Where. Att João Bosco Quote Link to comment Share on other sites More sharing options...
evandro Posted February 25, 2016 Report Share Posted February 25, 2016 Olá, O problema é o subselect, que também se faz presente na sugestão do João. Sugiro criar uma tabela temporária, criar um índice nesta tabela e relacionar (join) com a principal. Seria algo mais ou menos assim: create TEMPORARY table temp SELECT MAX(pe.data) AS data, pe.produto FROM pedido as pe WHERE pe.tipo='1' and data < '2015-11-30' GROUP BY pe.produto ORDER BY pe.produto; CREATE INDEX produto ON temp (produto); SELECT temp.data, prod.produto, prod.descricao FROM produto as prod LEFT JOIN temp ON prod.produto = temp.codigo; Quote Link to comment Share on other sites More sharing options...
Luiz Fernando Posted February 25, 2016 Author Report Share Posted February 25, 2016 João obrigado pela resposta, mais não adiantou, cancelei aos 15 minutos Evandro vou analisar sua resposta, realmente nunca mexi com tabela temporaria, tenho outros casos aqui de lentidão , vou tentar aplicar seu exemplo, obrigado. o select abaixo resolveu meu problema, criei mais uma subselect para pegar os dados do produto, inclusive apliquei uma terceira subselect para buscar o saldo(estoque),esta sendo processado em 53 segundos SELECT t1.data,t2.produto,t3.descricao,t2.qtd,t3.custo,t3.cadastro FROM (SELECT produto,SUM(qtd)AS qtd FROM estoque GROUP BY produto) AS T2, (SELECT MAX(DATA)AS DATA,produto FROM pedido WHERE tipo='1' GROUP BY produto ORDER BY produto) AS T1, (SELECT codigo,descricao,custo,cadastro FROM produto) AS T3 WHERE t1.produto=t2.produto AND t3.codigo=t1.produto AND DATA < '2015-11-30' AND qtd>0 Obs; o teste foi feito numa tabela(PEDIDO) com mais de 2 milhões de registros Obrigado a todos,. Quote Link to comment Share on other sites More sharing options...
Geraldo (gbsilva) Posted February 27, 2016 Report Share Posted February 27, 2016 Luiz tenho uma sugestão se quiser tentar. cSql := "SELECT sald.data,sald.produto,sald.descricao" +; " FROM (SELECT MAX(pe.data) AS data,pe.produto,pr.descricao" +; " FROM pedido AS pe" +; " INNER JOIN produto AS pr ON pe.produto = pr.codigo" +; " WHERE pe.tipo='1'" +; " GROUP BY pe.produto ) sald " +; " WHERE sald.data < '2015-11-30'" +; " ORDER BY sald.produto ; " Luiz Fernando 1 Quote Link to comment Share on other sites More sharing options...
Geraldo (gbsilva) Posted February 27, 2016 Report Share Posted February 27, 2016 Só umas considerações sobre o código, não sei se o que faço esta mais correto ou não, mas trabalho com tabelas com muitos registros e não tenho problema com lentidão. cSql="SELECT data,produto,descricao"cSql+=" FROM (SELECT MAX(pe.data) AS data,pe.produto,pr.descricao"cSql+=" FROM pedido as pe, produto as pr"cSql+=" WHERE pe.tipo='1'"cSql+=" AND pe.produto = pr.codigo"cSql+=" GROUP BY pe.produto"cSql+=" ORDER BY pe.produto) sald"cSql+=" WHERE data < '2015-11-30'" Por exemplo se tenho um sub-select e atribui o alias dele como sald os campos do select final sempre referencio como sald.campo. Outra coisa as tabelas pedido e produto uso um ON para relacioná-las e nunca um AND no WHERE como no código. Terceiro nunca coloco ORDER BY no sub-select faço no final usando o alias como coloquei na minha sugestão. Mestre Evandro também não utilizo temporárias e gostei do seu exemplo, qualquer hora farei algum teste para ver se posso melhorar minhas consultas. Sds a todos, Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.