Jump to content
Fivewin Brasil

Sugestão de select


Luiz Fernando

Recommended Posts

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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;

Link to comment
Share on other sites

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,.

Link to comment
Share on other sites

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 ; "

Link to comment
Share on other sites

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,

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...