Usuário com melhor resposta
Sub Query demora

Pergunta
-
Olá a todos,
Fiz uma consulta para retornar os produtos que NÃO tiveram movimentações no estoque do meu trabalho, em um determinado período. A consulta funciona bem, porém, o tempo de execução é muito alto (cerca de 3 min), e para colocar em produção para um usuário, isso se torna quase inviável.
Segue query:
SELECT DISTINCT A.CODIGOPRD, A.NOMEFANTASIA, B.SALDOFISICO2, A.CUSTOUNITARIO, A.CODUNDCONTROLE, A.CODUNDCOMPRA, A.CODUNDVENDA FROM TPRD A, TPRDLOC B, SZPRD C WHERE A.IDPRD = B.IDPRD AND B.IDPRD = C.IDPRD AND B.CODLOC = 002 AND A.INATIVO = 0 AND C.TIPOITEM = 'A' AND B.SALDOFISICO2 > 0 AND A.IDPRD NOT IN (SELECT DISTINCT A.IDPRD FROM TITMMOV A, TMOV B WHERE A.IDMOV = B.IDMOV AND B.CODTMV IN ('2.2.08','2.2.16','2.2.12','2.2.10') AND B.DATAMOVIMENTO >= '2013-03-01' AND B.DATAMOVIMENTO <= '2013-03-10' ) ORDER BY NOMEFANTASIA
Alguém tem alguma sugestão de como melhorar a rapidez de execução da minha query?
Obrigado.
Gabriel Alves.
- Editado galves.rod terça-feira, 30 de abril de 2013 11:03 Erro
Respostas
-
Boa tarde,
Experimente dessa forma:
with CTE_M as ( SELECT DISTINCT A.IDPRD FROM TITMMOV A INNER JOIN TMOV B ON B.IDMOV = A.IDMOV
WHERE B.CODTMV IN ('2.2.08','2.2.16','2.2.12','2.2.10') AND B.DATAMOVIMENTO BETWEEN '2013-03-01' AND '2013-03-10' ) SELECT DISTINCT A.CODIGOPRD, A.NOMEFANTASIA, B.SALDOFISICO2, A.CUSTOUNITARIO, A.CODUNDCONTROLE, A.CODUNDCOMPRA, A.CODUNDVENDA FROM TPRD A INNER JOIN TPRDLOC B ON B.IDPRD = A.IDPRD INNER JOIN SZPRD C ON C.IDPRD = B.IDPRD WHERE B.CODLOC = 002 AND A.INATIVO = 0 AND C.TIPOITEM = 'A' AND B.SALDOFISICO2 > 0 AND NOT EXISTS (SELECT 1 FROM CTE_M AS M WHERE M.IDPRD = A.IDPRD) ORDER BY NOMEFANTASIA
Espero que ajude.
Assinatura: http://www.imoveisemexposicao.com.br
- Editado gapimex segunda-feira, 29 de abril de 2013 19:40
- Marcado como Resposta galves.rod quinta-feira, 2 de maio de 2013 15:23
-
Deleted
- Marcado como Resposta galves.rod quinta-feira, 2 de maio de 2013 15:23
Todas as Respostas
-
Boa tarde,
Experimente dessa forma:
with CTE_M as ( SELECT DISTINCT A.IDPRD FROM TITMMOV A INNER JOIN TMOV B ON B.IDMOV = A.IDMOV
WHERE B.CODTMV IN ('2.2.08','2.2.16','2.2.12','2.2.10') AND B.DATAMOVIMENTO BETWEEN '2013-03-01' AND '2013-03-10' ) SELECT DISTINCT A.CODIGOPRD, A.NOMEFANTASIA, B.SALDOFISICO2, A.CUSTOUNITARIO, A.CODUNDCONTROLE, A.CODUNDCOMPRA, A.CODUNDVENDA FROM TPRD A INNER JOIN TPRDLOC B ON B.IDPRD = A.IDPRD INNER JOIN SZPRD C ON C.IDPRD = B.IDPRD WHERE B.CODLOC = 002 AND A.INATIVO = 0 AND C.TIPOITEM = 'A' AND B.SALDOFISICO2 > 0 AND NOT EXISTS (SELECT 1 FROM CTE_M AS M WHERE M.IDPRD = A.IDPRD) ORDER BY NOMEFANTASIA
Espero que ajude.
Assinatura: http://www.imoveisemexposicao.com.br
- Editado gapimex segunda-feira, 29 de abril de 2013 19:40
- Marcado como Resposta galves.rod quinta-feira, 2 de maio de 2013 15:23
-
-
Gabriel, confirma uma coisa... aquela query que você postou no inicio está retornando os produtos com movimento, certo?
Assinatura: http://www.imoveisemexposicao.com.br
-
-
-
Deleted
- Marcado como Resposta galves.rod quinta-feira, 2 de maio de 2013 15:23
-
José,
Concordo com a sua sugestão de retirar o Distinct.
Abraço
Assinatura: http://www.imoveisemexposicao.com.br
-
Bom dia José Diz e gapimex,
Fiz os testes solicitados e só o fato de ter tirada o 'Distinct' da query, conforme sugeriu o José Diz, agilizou bastante a consulta.
Analisei o plano de execução e, assim como ele disse, existem operações que estão com um alto custo do CPU. Link para baixar o arquivo: http://www.sendspace.com/file/9usob9.
Verifiquei se existia index pela data do movimento, existe.
CREATE NONCLUSTERED INDEX [TXMOVDTM] ON [dbo].[TMOV] ( [DATAMOVIMENTO] ASC, [CODCOLIGADA] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY] GO
Obrigado.
Gabriel Alves.
-
-
Considerando o mês inteiro, leva cerca de 1 minuto e 15 segundo. Acho que é o melhor que dá pra fazer, pois acredito que o tempo gasto é devido à quantidade de informações presentes. Acho que vou entregar o relatório, e informar que o relatório levará alguns minutos para ser apresentado.
Mais isso não prejudicará muito o trabalho do usuário ou o processamento do servidor, já que o intuito desse relatório é ser tirado uma vez por mês.
Se você concordar, vou marcar o poste como respondido.
-
-
-
Esqueci de comentar,
O BD é da TOTVS, desenvolvido pela antiga RM, não me sinto nenhum pouco seguro incluindo ou alterando a estrutura do BD, tal como os índices. Poderia até incluir a coluna no TXMOVDTM, mais em base teste. Oficialmente eu não faria.