sp_cursoropen e paralelismo


15

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.

insira a descrição da imagem aqui

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.

insira a descrição da imagem aqui

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

insira a descrição da imagem aqui

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)

Respostas:


20

FAST_FORWARDos cursores não oferecem suporte ao paralelismo (embora o servidor que gera o plano precisaria ser 2012 ou superior para fazer NonParallelPlanReasonparte do XML do plano de show).

Quando você especifica FAST_FORWARD, o otimizador escolhe entre STATICe DYNAMICpara você.

O plano de execução fornecido mostra o otimizador escolhendo um plano de estática. Como a consulta contém agregação, duvido que um plano dinâmico de cursor seja possível aqui. No entanto, solicitar um FAST_FORWARDtipo de cursor está impedindo um plano paralelo.

Você deve alterar explicitamente o tipo de cursor para um STATICou KEYSET, por exemplo. Ambos os tipos de cursor podem usar paralelismo.

Dito isto, como este é um cursor da API, a alteração do tipo de cursor provavelmente exigiria uma alteração no aplicativo. Naturalmente, você precisaria avaliar o desempenho para verificar se alterar o tipo do cursor é realmente a melhor opção para você.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.