sp_cursoropen 및 병렬 처리


15

머리를 get 수없는 쿼리로 성능 문제가 발생했습니다.

커서 정의에서 쿼리를 가져 왔습니다.

이 쿼리는 실행하는 데 몇 초가 걸립니다

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)지원되지 않는다는 것을 알고 있지만 적합하다고 생각되면이 인스턴스를 업그레이드 할 수 없습니다. 데이터베이스를 다른 서버로 전송해야하므로 느린 WAN을 통해 상당히 큰 압축되지 않은 백업을 가져옵니다.

추적 플래그 4199는 차이가 없으며 OPTION (RECOMPILE)도 마찬가지입니다.

커서 속성은 다음과 같습니다.

API | Fast_Forward | Read Only | Global (0)

답변:


20

FAST_FORWARD커서 는 병렬 처리를 지원하지 않습니다 (계획을 생성하는 서버 NonParallelPlanReason는 실행 계획 XML의 일부로 가져 오려면 2012 이상이어야 함 ).

당신이 지정하는 경우 FAST_FORWARD, 옵티마이 저는 선택 사이 STATICDYNAMIC당신을 위해.

제공된 실행 계획은 옵티마이 저가 정적 계획을 선택하는 것을 보여줍니다. 쿼리에 집계가 포함되어 있기 때문에 여기에서 동적 커서 계획이 가능한지 의심됩니다. 그럼에도 불구하고 FAST_FORWARD커서 유형을 요청 하면 병렬 계획이 방지됩니다.

예를 들어 커서 유형을 명시 적으로 STATIC또는로 변경해야합니다 KEYSET. 이 두 커서 유형 모두 병렬 처리를 사용할 수 있습니다.

즉, 이것은 API 커서이므로 커서 유형을 변경하면 응용 프로그램 변경이 필요할 수 있습니다. 당연히 커서 유형 변경이 실제로 가장 적합한 옵션인지 확인하려면 성능을 벤치마킹해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.