Я столкнулся с проблемой производительности с запросом, который, кажется, не может заставить меня задуматься.
Я вытащил запрос из определения курсора.
Этот запрос занимает несколько секунд, чтобы выполнить
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
Фактический план выполнения выглядит следующим образом.
Заметив, что для параметра сервера установлено значение MaxDOP 1 Я попытался поиграться с настройками maxdop.
Добавление OPTION (MAXDOP 0)
к запросу или изменение настроек сервера приводит к гораздо большей производительности и этому плану запроса.
Однако рассматриваемое приложение (Dynamics AX) не выполняет подобные запросы, оно использует курсоры.
Фактический код захвачен это.
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
в результате этого плана выполнения (и, к сожалению, то же время выполнения несколько секунд).
Я пробовал несколько вещей, таких как удаление кэшированных планов, добавление опций в запросе внутри определения курсора ... Но, похоже, ни одна из них не дает мне параллельный план.
Я также искал в Google довольно много в поисках ограничений параллельности курсоров, но не могу найти никаких ограничений.
Я что-то упускаю здесь очевидное?
Реальная сборка SQL, как SQL Server 2008 (SP1) - 10.0.2573.0 (X64)
я понимаю, не поддерживается, но я не могу обновить этот экземпляр так, как считаю нужным. Мне нужно было перенести базу данных на другой сервер, и это означало бы перетаскивание довольно большой несжатой резервной копии по медленной глобальной сети.
Флаг трассировки 4199 не имеет значения, равно как и OPTION (RECOMPILE).
Свойства курсора:
API | Fast_Forward | Read Only | Global (0)