SQL Server 2012 ile bir Dynamics AX 2012 yüklemesi yapıyoruz. İmleçlerin artık kullanılmaması gerektiğini biliyorum, ancak AX bunu kullanıyor ve bu davranışı değiştiremeyiz, bu yüzden onunla çalışmak zorundayız.
Bugün 53 milyondan fazla okuma ve 20 dakikadan fazla yürütme süresi ile çok kötü bir sorgu yakaladım.
Bu sorguyu SentryOne izleme aracımızla yakaladım.
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
Fark ettiğim ilk şey, bu sorgunun bir imleç kullanmasıydı. Merak dışında ifade kopyaladı ve imleç şeyler olmadan Management Studio yürüttüm (Ben çalıştırmak için böylece sorgu için parametreleri yerine itiraf etmeliyim). SSMS içinde sorgu 30 saniye içinde tamamlandı. Çok hızlı değil, ama yine de imleç alternatifinden daha hızlı.
Burada her iki planı da sağlıyorum:
- İmleçle plan yap: https://www.brentozar.com/pastetheplan/?id=Sk0aMY-Y-
- İmleçsiz plan: https://www.brentozar.com/pastetheplan/?id=HJ6ImtWK-
İmleçsiz plan hala çok kötü bir plan ama çok daha iyi. Sorum şu: Birisi bana imleç versiyonunun neden 53 milyon okumaya ihtiyacı olduğunu açıklayabilir mi?
İmleç ile sorgu için istatistikler:
Duration CPU Reads Writes Est Rows Actual Rows
1.396.212 1.379.157 53.270.895 3.878 30 2
İmleçsiz sorgu için istatistikler:
Duration CPU Reads Writes Est Rows Actual Rows
23.337 1.703 665.113 13 4.287 34.813
2 yerine 34.813 satır almak garip görünüyor; ama doğru parametreleri doldurduğuma eminim. İstatistikleri oradan kopyaladığım için SQL Sentry'den belki de komik bir tuhaflık olduğunu düşündüm.
Umarım sana gerekli tüm bilgileri verebilirim. Ayrıca kimse iyi okumalar varsa daha iyi olurdu imleçler daha iyi anlamak.