Ich habe ein Leistungsproblem mit einer Abfrage, die mir nicht klar ist.
Ich habe die Abfrage aus einer Cursordefinition gezogen.
Die Ausführung dieser Abfrage dauert Sekunden
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
Der tatsächliche Ausführungsplan sieht so aus.
Beachten Sie, dass die serverweite Einstellung auf MaxDOP 1 festgelegt wurde. Ich habe versucht, mit den maxdop-Einstellungen herumzuspielen.
Durch Hinzufügen OPTION (MAXDOP 0)
zur Abfrage oder Ändern der Servereinstellungen werden die Leistung und der Abfrageplan erheblich verbessert.
Die betreffende Anwendung (Dynamics AX) führt jedoch keine derartigen Abfragen aus, sondern verwendet Cursor.
Der tatsächlich erfasste Code ist dieser.
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
Daraus resultiert dieser Ausführungsplan (und leider die gleichen Ausführungszeiten von mehreren Sekunden).
Ich habe verschiedene Dinge ausprobiert, wie das Löschen von zwischengespeicherten Plänen, das Hinzufügen von Optionen in der Abfrage innerhalb der Cursordefinition, ... Aber keiner von ihnen scheint mir einen parallelen Plan zu liefern.
Ich habe auch in Google nach Parallelitätsbeschränkungen von Cursorn gesucht, kann aber anscheinend keine Einschränkungen feststellen.
Vermisse ich hier etwas Offensichtliches?
Der eigentliche SQL-Build wird SQL Server 2008 (SP1) - 10.0.2573.0 (X64)
meines Erachtens nicht unterstützt, aber ich kann diese Instanz nicht aktualisieren, wie ich es für richtig halte. Ich müsste die Datenbank auf einen anderen Server übertragen, und das würde bedeuten, eine ziemlich große unkomprimierte Sicherung über ein langsames WAN zu ziehen.
Das Trace-Flag 4199 macht keinen Unterschied und OPTION (RECOMPILE) auch nicht.
Die Cursoreigenschaften sind:
API | Fast_Forward | Read Only | Global (0)