Kami menjalankan instalasi Dynamics AX 2012 dengan SQL Server 2012. Saya tahu bahwa kursor tidak boleh digunakan lagi tetapi AX menggunakannya dan kami tidak dapat mengubah perilaku ini sehingga kami harus bekerja dengannya.
Hari ini saya menangkap permintaan yang sangat buruk dengan lebih dari 53 juta bacaan dan waktu eksekusi lebih dari 20 menit.
Saya menangkap kueri ini melalui alat pemantauan kami SentryOne.
declare @p1 int
set @p1=1073773227
declare @p2 int
set @p2=180158805
declare @p5 int
set @p5=16
declare @p6 int
set @p6=1
declare @p7 int
set @p7=2
exec sp_cursorprepexec @p1 output,@p2 output,N'@P1 bigint,@P2 nvarchar(5),@P3 bigint,@P4 nvarchar(8),@P5 bigint,@P6 bigint,@P7 bigint,@P8 bigint,@P9 bigint,@P10 bigint,@P11 bigint,@P12 bigint,@P13 bigint,@P14 bigint,@P15 bigint,@P16 bigint,@P17 bigint,@P18 bigint,@P19 nvarchar(5),@P20 bigint,@P21 bigint,@P22 bigint,@P23 bigint,@P24 bigint',N'SELECT T1.PRODUCT,T1.EXTERNALVENDPARTY,T1.LIFECYCLESTATUS,T1.RECID,T2.ECORESPRODUCT,T2.ECORESDISTINCTPRODUCTVARIANT,T2.SGE,T2.ECORESREFORDERNUM,T2.ORDERNUM,T2.RECID,T3.ECORESREFORDERNUM,T3.NAME1,T3.NAME2,T3.NAME3,T3.RECID,T4.ECORESPRODUCT,T4.EXTERNALITEMID,T4.ECORESDISTINCTPRODUCTVARIANT,T4.RECID,T5.RECID,T5.PERSON,T6.RECID,T6.NAME,T6.INSTANCERELATIONTYPE,T7.RECID,T7.NAME,T7.INSTANCERELATIONTYPE,T8.PARTY,T8.ACCOUNTNUM,T8.RECID,T9.RECID,T9.DISPLAYPRODUCTNUMBER,T9.INSTANCERELATIONTYPE,T10.PRODUCT,T10.CATEGORY,T10.RECID,T11.RECID,T11.CODE,T11.NAME,T11.INSTANCERELATIONTYPE FROM INVENTTABLE T1 CROSS JOIN ECORESPRODUCTORDERNUM T2 CROSS JOIN ECORESPRODUCTORDERNUMTRANSLATION T3 LEFT OUTER JOIN VENDEXTERNALITEM T4 ON ((T4.PARTITION=5637144576) AND ((T2.ECORESPRODUCT=T4.ECORESPRODUCT) AND (T4.ECORESDISTINCTPRODUCTVARIANT=@P1))) CROSS JOIN HCMWORKER T5 CROSS JOIN DIRPARTYTABLE T6 CROSS JOIN DIRPARTYTABLE T7 CROSS JOIN VENDTABLE T8 CROSS JOIN ECORESPRODUCT T9 CROSS JOIN ECORESPRODUCTCATEGORY T10 CROSS JOIN ECORESCATEGORY T11 WHERE (((T1.PARTITION=5637144576) AND (T1.DATAAREAID=N''087'')) AND (T1.DATAAREAID=@P2)) AND ((T2.PARTITION=5637144576) AND ((T2.ECORESPRODUCT=T1.PRODUCT) AND (T2.SGE=@P3))) AND ((T3.PARTITION=5637144576) AND ((T3.ECORESREFORDERNUM=T2.ECORESREFORDERNUM) AND (T3.LANGUAGEID=@P4))) AND ((T5.PARTITION=5637144576) AND (T5.RECID=T2.PRODUCTMANAGER)) AND (((T6.PARTITION=5637144576) AND (T6.INSTANCERELATIONTYPE IN (@P5,@P6,@P7,@P8,@P9,@P10,@P11) )) AND (T6.RECID=T5.PERSON)) AND (((T7.PARTITION=5637144576) AND (T7.INSTANCERELATIONTYPE IN (@P12,@P13,@P14,@P15,@P16,@P17,@P18) )) AND (T1.EXTERNALVENDPARTY=T7.RECID)) AND (((T8.PARTITION=5637144576) AND (T8.DATAAREAID=N''087'')) AND ((T7.RECID=T8.PARTY) AND (T8.DATAAREAID=@P19))) AND (((T9.PARTITION=5637144576) AND (T9.INSTANCERELATIONTYPE IN (@P20,@P21,@P22) )) AND (T9.RECID=T1.PRODUCT)) AND ((T10.PARTITION=5637144576) AND (T10.PRODUCT=T9.RECID)) AND (((T11.PARTITION=5637144576) AND (T11.INSTANCERELATIONTYPE IN (@P23,@P24) )) AND (T11.RECID=T10.CATEGORY))',@p5 output,@p6 output,@p7 output,0,N'087',5637146082,N'de',41,2303,2377,2975,2978,5329,6886,41,2303,2377,2975,2978,5329,6886,N'087',3265,3266,3267,2665,4423
select @p1, @p2, @p5, @p6, @p7
Hal pertama yang saya perhatikan adalah bahwa kueri ini menggunakan kursor. Karena penasaran, saya menyalin pernyataan dan menjalankannya di Management Studio tanpa hal-hal kursor (saya harus mengakui bahwa saya mengganti parameter untuk kueri sehingga saya bisa menjalankannya). Dalam SSMS kueri selesai dalam 30 detik. Tidak terlalu cepat, tetapi masih lebih cepat daripada alternatif kursor.
Di sini saya memberikan Anda berdua paket:
- Paket dengan kursor: https://www.brentozar.com/pastetheplan/?id=Sk0aMY-Y-
- Paket tanpa kursor: https://www.brentozar.com/pastetheplan/?id=HJ6ImtWK-
Rencana tanpa kursor masih merupakan rencana yang sangat buruk tetapi jauh lebih baik. Pertanyaan saya di sini adalah: Dapatkah seseorang tolong jelaskan kepada saya mengapa versi kursor membutuhkan 53 juta bacaan?
Statistik untuk kueri dengan kursor:
Duration CPU Reads Writes Est Rows Actual Rows
1.396.212 1.379.157 53.270.895 3.878 30 2
Statistik untuk kueri tanpa kursor:
Duration CPU Reads Writes Est Rows Actual Rows
23.337 1.703 665.113 13 4.287 34.813
Tampaknya aneh untuk mendapatkan 34.813 baris, bukan 2; tapi saya cukup yakin bahwa saya mengisi parameter yang tepat. Saya pikir ini mungkin kekhasan lucu dari SQL Sentry karena saya baru saja menyalin statistik dari sana.
Saya harap saya bisa memberikan Anda semua informasi yang diperlukan untuk Anda. Juga jika ada yang memiliki bacaan yang baik, lebih baik memahami kursor yang akan lebih bagus.