sp_cursoropenと並列処理


15

私は頭を悩ませることができないように見えるクエリでパフォーマンスの問題に直面しています。

カーソル定義からクエリを引き出しました。

このクエリの実行には数秒かかります

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は、showplan XMLの一部として取得するには2012以上である必要があります)。

あなたが指定した場合FAST_FORWARDオプティマイザは、選択したSTATICDYNAMIC、あなたのために。

提供された実行計画は、オプティマイザーが静的な計画を選択していることを示しています。クエリには集計が含まれているため、ここでは動的なカーソルプランも可能だとは思いません。それでも、FAST_FORWARDカーソルタイプを要求すると、並列プランが妨げられます。

たとえば、カーソルタイプを明示的にSTATICまたはのいずれかに変更する必要がありますKEYSET。これらのカーソルタイプは両方とも並列処理を使用できます。

ただし、これはAPIカーソルであるため、カーソルのタイプを変更するにはアプリケーションの変更が必要になる可能性があります。当然、カーソルタイプの変更が本当に最適なオプションであることを確認するために、パフォーマンスのベンチマークを行う必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.