Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

victorpavia

performance de consulta

Recommended Posts

Pessoal tenho essa consulta abaixo que esta carregada porque tem uma subconsulta no join que esta pesando demais. Gostaria, se possível, de sugestões para melhorá-la.

No caso preciso pegar a data da 1ª compra do cliente.

 

Destaquei a subconsulta que esta me dando problemas. Muito obrigado.

 

SELECT tm.STATUS,tm.CODTDO,tm.NUMEROMOV, FCFO.NOME,FCFO.CODCFO, tm.DATAEMISSAO, tm.valorliquido, FCFO.USUARIOCRIACAO,tm.VALORDESC,tm.VALORDESP,tm.STATUS,

(SELECT NOME FROM FCFODEF INNER JOIN TCPG ON (TCPG.CODCPG = FCFODEF.CODCPG) WHERE CODCFO = FCFO.CODCFO) AS PRAZO,
data1compra,
SUM(case when tprd.margembrutalucro >= 1.15 and tprd.margembrutalucro <= 1.30 then (titmmov.precounitario*titmmov.quantidade) *
case when tm.codven1 = '0003' then 0.02 else 0.01 end
when tprd.margembrutalucro >= 1.31 and tprd.margembrutalucro <= 1.50 then (titmmov.precounitario*titmmov.quantidade) *
case when tm.codven1 = '0003' then 0.022 else 0.012 end
when TPRD.MARGEMBRUTALUCRO = 1.51 then (titmmov.precounitario*titmmov.quantidade) * 0.1
else 0 end) as valorlucro
,case when tm.codven1 is null then fd.CODVEN else tm.codven1 end as codven1
FROM
(select fc.codcfo,min(tm.dataemissao)as data1compra from tmov tm WITH (NOLOCK)
inner join fcfo fc (NOLOCK) on (tm.codcfo = fc.codcfo)
where codtmv in('2.2.01','2.2.29','2.2.14','2.2.25','2.2.02')
group by fc.codcfo)t1
inner join tmov tm (NOLOCK) on (tm.codcfo = t1.codcfo)
INNER JOIN FCFO (NOLOCK) ON (FCFO.CODCFO = tm.CODCFO)
left join FCFODEF fd on (fd.CODCFO = FCFO.CODCFO)
INNER JOIN TITMMOV (NOLOCK) ON (TITMMOV.IDMOV = tm.IDMOV)
INNER JOIN TPRD (NOLOCK) ON (TPRD.IDPRD = TITMMOV.IDPRD)
LEFT JOIN TMOVCOMPL (NOLOCK) ON (TMOVCOMPL.IDMOV = tm.IDMOV)
left join DNFEINUT d (NOLOCK) on (d.NUMDOC = tm.NUMEROMOV)
LEFT JOIN VAREJAOCEREAIS.DBO.CONTROLELICIT CLICIT (NOLOCK) ON (CODLICITACAO = NUMLICITcao collate database_default)
WHERE tm.DATAEMISSAO>='20/10/2013'
AND tm.DATAEMISSAO<='20/11/2013'
AND tm.STATUS <> 'C' AND tm.CODCFO = FCFO.CODCFO
and codtmv in('2.2.01','2.2.29','2.2.14','2.2.25','2.2.02')
AND tm.codcfo not in('000337') and FCFO.CODCFO <> '000337'
and d.NUMDOC is null
GROUP BY tm.CODTDO,NUMEROMOV, NOME,FCFO.CODCFO, tm.DATAEMISSAO,
tm.valorliquido, FCFO.USUARIOCRIACAO,tm.VALORDESC,tm.VALORDESP,tm.STATUS,
data1compra,
tm.codven1,fd.codven
,CLICIT.FUNCIONARIO
ORDER BY tm.dataemissao

Compartilhar este post


Link para o post
Compartilhar em outros sites

Teria como tirar este subselect, em geral nao e bom usa-los.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu tinha um problema parecido com esse e resolvi usando uma cláusula chamada Cross Apply em resumo ela faz um join com um função do tipo tabela.

 

 

Segue link com esse recurso

 

http://technet.microsoft.com/pt-br/library/ms175156(v=sql.105).aspx

Compartilhar este post


Link para o post
Compartilhar em outros sites

Subselect geralmente degrada e muito a pesquisa.

Além do Apply postado pelo Daniel, tente utilizar um LEFT ou segregar seu subselect em uma temporaria antes desta consulta.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Se eu remover a subconsulta como vou ver a data da primeira compra do cliente? É justamente isso que preciso.

Abri o tópico para tentar uma solução alternativa.



Senhores,

 

Apenas coloquei a subquery no left join assim:

 

FROM tmov tm
left join
(select fc.codcfo,min(tm.dataemissao)as data1compra from tmov tm WITH (NOLOCK)
inner join fcfo fc (NOLOCK) on (tm.codcfo = fc.codcfo)
where codtmv in('2.2.01','2.2.29','2.2.14','2.2.25','2.2.02')
group by fc.codcfo)t1
on (tm.codcfo = t1.codcfo)
A performance melhorou significativamente.
Muito obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.