Estou com um problema de desempenho com uma consulta que não consigo entender.
Tirei a consulta de uma definição de cursor.
Esta consulta leva segundos para executar
SELECT A.JOBTYPE
FROM PRODROUTEJOB A
WHERE ((A.DATAAREAID=N'IW')
AND ((A.CALCTIMEHOURS<>0)
AND (A.JOBTYPE<>3)))
AND EXISTS (SELECT 'X'
FROM PRODROUTE B
WHERE ((B.DATAAREAID=N'IW')
AND (((((B.PRODID=A.PRODID)
AND ((B.PROPERTYID=N'PR1526157') OR (B.PRODID=N'PR1526157')))
AND (B.OPRNUM=A.OPRNUM))
AND (B.OPRPRIORITY=A.OPRPRIORITY))
AND (B.OPRID=N'GRIJZEN')))
AND NOT EXISTS (SELECT 'X'
FROM ADUSHOPFLOORROUTE C
WHERE ((C.DATAAREAID=N'IW')
AND ((((((C.WRKCTRID=A.WRKCTRID)
AND (C.PRODID=B.PRODID))
AND (C.OPRID=B.OPRID))
AND (C.JOBTYPE=A.JOBTYPE))
AND (C.FROMDATE>{TS '1900-01-01 00:00:00.000'}))
AND ((C.TODATE={TS '1900-01-01 00:00:00.000'}))))))
GROUP BY A.JOBTYPE
ORDER BY A.JOBTYPE
O plano de execução real se parece com isso.
Percebendo que a configuração do servidor foi definida como MaxDOP 1 Tentei brincar com as configurações do maxdop.
Adicionando OPTION (MAXDOP 0)
à consulta ou alterar as configurações do servidor resulta em um desempenho muito melhor e neste plano de consulta.
No entanto, o aplicativo em questão (Dynamics AX) não executa consultas como essa, usa cursores.
O código real capturado é este.
declare @p1 int
set @p1=189527589
declare @p3 int
set @p3=16
declare @p4 int
set @p4=1
declare @p5 int
set @p5=2
exec sp_cursoropen @p1 output,N'SELECT A.JOBTYPE FROM PRODROUTEJOB A WHERE ((A.DATAAREAID=N''IW'') AND ((A.CALCTIMEHOURS<>0) AND (A.JOBTYPE<>3))) AND EXISTS (SELECT ''X'' FROM PRODROUTE B WHERE ((B.DATAAREAID=N''IW'') AND (((((B.PRODID=A.PRODID) AND ((B.PROPERTYID=N''PR1526157'') OR (B.PRODID=N''PR1526157''))) AND (B.OPRNUM=A.OPRNUM)) AND (B.OPRPRIORITY=A.OPRPRIORITY)) AND (B.OPRID=N''GRIJZEN''))) AND NOT EXISTS (SELECT ''X'' FROM ADUSHOPFLOORROUTE C WHERE ((C.DATAAREAID=N''IW'') AND ((((((C.WRKCTRID=A.WRKCTRID) AND (C.PRODID=B.PRODID)) AND (C.OPRID=B.OPRID)) AND (C.JOBTYPE=A.JOBTYPE)) AND (C.FROMDATE>{TS ''1900-01-01 00:00:00.000''})) AND ((C.TODATE={TS ''1900-01-01 00:00:00.000''})))))) GROUP BY A.JOBTYPE ORDER BY A.JOBTYPE ',@p3 output,@p4 output,@p5 output
select @p1, @p3, @p4, @p5
resultando neste plano de execução (e infelizmente os mesmos tempos de execução de vários segundos).
Eu tentei várias coisas, como descartar planos em cache, adicionar opções na consulta dentro da definição do cursor, ... Mas nenhum deles me parece um plano paralelo.
Também procurei no google um pouco procurando por limitações de cursores em paralelismo, mas parece que não consigo encontrar nenhuma limitação.
Estou perdendo algo óbvio aqui?
A compilação SQL real é SQL Server 2008 (SP1) - 10.0.2573.0 (X64)
que eu percebo que não é suportada, mas não posso atualizar esta instância como achar melhor. Eu precisaria transferir o banco de dados para outro servidor e isso significaria extrair um backup descompactado bastante grande em uma WAN lenta.
O sinalizador de rastreamento 4199 não faz diferença e OPTION (RECOMPILE).
As propriedades do cursor são:
API | Fast_Forward | Read Only | Global (0)
fonte