Array
(
)

performance de consulta

Victor Pavia
   - 20 nov 2013

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.
O problema esta nessa subconsulta:
" (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"

Campo: data1compra

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

Isaac Jose
   - 20 nov 2013

vi por cima mais parece consulta para algum relatório ou sistema é isso???
se for eu costumo separar ao máximo possível e depois mesmo com case,sum group by comparação eu crio uma outra table.. para que essa ultima sem nenhuma operação seja efetuada as consultas no seu caso com data da primeira compra. .. isso para relatórios e sistemas é o mais performático q conheço..

se não for isso favor comunicar..

Roniere Almeida
   - 21 nov 2013

alguem conhece algum material que ajude nessa questão? pode ser livro, apostila.

Isaac Jose
   - 21 nov 2013


Citação:
alguem conhece algum material que ajude nessa questão? pode ser livro, apostila.


eu constumo utilizar no 2008 o plano de execução (execution plan) para avaliar exatamente em que momento esta ocorrendo a sobrecarga.
porem é interessante saber pontos como .. ambiente..(producao,relatorio)se estao ou estiverem separados em bancos diferentes se tem a possibilidade de criar um unico banco com a base consolidada...
se é possivel criar outras tables com as consolidações ja feitas..
se a table for de uso interno (nacional) verificar se nao foram criados campos de quantidade de caracteres pequena com valores ex (ntext,nchar,nvarchar) que deixa qualquer consulta uma carroça obs (rsrsr)
e assim por diante..

pois bem para performace nao conheço nada melhor do que o plano de execução..

Roniere Almeida
   - 21 nov 2013

Isaac, essa questão de escolha de dados é um ponto importante a se pensa em longo prazo, ou melhor, evita problemas futuros.

Isaac Jose
   - 21 nov 2013


Citação:
Isaac, essa questão de escolha de dados é um ponto importante a se pensa em longo prazo, ou melhor, evita problemas futuros.
]

boa noite amigo .... pense que é importante pensar em problemas a longo prazo já que dependendo do ambiente não se sabe o tamanho que o banco ira obter ao longo de sua vida.
exemplo ... tenho uma table hoje nova... com 2.5 bi de linhas... com insert mensal de 250 milhões...por isso a importância de saber o que estamos criando e como estamos criando.
ex peguei uma situação de um colega essa semana que vinha me falando o quão seus sistemas demoravam para fazer atualizações com números totalmente modestos comparados aos que eu tenho. com isso fui ver o que poderia ser feito. de cara me depareis com campos nvarchar que ocupam nada menos de que 65500 e poucas combinações para um campo que ele precisava por exemplo identificar 1 CARACTER M OU F . ou seja para saber se e masculino ou feminino .. quis saber o pq daqueles campos e ele me disse que quando foram lançados nas versões mais atuais leu que eram mais robustos que os outros... o que realmente são porem ele não sabia o tamanho de tudo isso. com as melhorias que eu sugeri a ele. a performance teve melhoria superior a 80% o banco teve uma redução no tamanho de mais de 87%.. por isso que sempre considero e recomendo o estudo que elementos que melhorem a performance.... obs... eu sou um puta preguiçoso rsrs não estudo nem fodendo mais tive que ver algumas coisas.. com isso realizei os cursos SQL 2778,6231,6232,6234,6235 so me falta o 6236 para completar os módulos do 2008 porem não terei a oportunidade de fazer o mesmo pois já mudou a versão.. esse realmente não me faz diferença pois possuo conhecimento superior ao que passam no curso i irei fazer um do 2012... mais no dia a dia em ambientes de alta performance.....e eu volto a frisar altíssima performance vc aprende algumas coisas e para mim algo extremamente essencial e a performance ....
e que eu puder agregar aos amigos com o pouco que conheço será um prazer :)
boa noite a todos

Roniere Almeida
   - 22 nov 2013

sim, sem duvida, vai fazer o curso aonde?

Isaac Jose
   - 22 nov 2013


Citação:
sim, sem duvida, vai fazer o curso aonde?


KASOLUTION.... a proposito... errei na quantidade acima... a mesma é de registro..
a escolha possui otimos professores alguns nem tanto mais no geral sao muito bons. o problema e o tempo de formação de turma que costuma demorar

Victor Pavia
   - 26 nov 2013

favor focar no assunto do tópico. Obrigado.

Victor Pavia
   - 26 nov 2013

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.

Isaac Jose
   - 26 nov 2013

desculpe se em algum comentário do tópico a questão de performance ficou ou foi destorcida

att

Isaac

Roniere Almeida
   - 28 nov 2013


Citação:

Citação:
sim, sem duvida, vai fazer o curso aonde?


KASOLUTION.... a proposito... errei na quantidade acima... a mesma é de registro..
a escolha possui otimos professores alguns nem tanto mais no geral sao muito bons. o problema e o tempo de formação de turma que costuma demorar


tem cursos online nesse local?

Isaac Jose
   - 28 nov 2013

bom dia... tem sim .... segue. http://www.kasolution.com.br/

Roniere Almeida
   - 11 dez 2013

obrigado Isaac.