Microsoft har förbättrat innehållet i ShowplanXML-utdata för SQL Server under de senaste versionerna och i SQL Server 2017 CU3 introducerade de exekveringsstatistik för användardefinierad funktion (UDF) i QueryTimeStats-noden för XML-utdata. Detta portades också tillbaka till SQL Server 2016 i Service Pack 2 för faktiska exekveringsplaner. Den här funktionen låter dig definitivt känna till effekten av skalär UDF-körning som en del av en frågas prestandaegenskaper. Det finns dock en intressant hake förknippad med att använda denna funktion; du måste samla in den faktiska exekveringsplanen med en uppdaterad version av SQL Server Management Studio eller med SentryOne Plan Explorer, annars kommer informationen att tas bort från exekveringsplanen.
Jämföra planer i olika SSMS-versioner
Jag presenterade nyligen en användargruppssession i Chicago om justering av frågeprestanda med hjälp av plancachen och under sessionen använde jag den senaste versionen av SQL Server Management Studio vid den tiden, version 17.5. Vid den tidpunkten hade jag också nyligen uppdaterat min virtuella dator till SQL Server 2016 Service Pack 2, så jag demonstrerade den nya UdfElapsedTime- och UdfCpuTime-informationen i själva showplanen QueryTimeStats och gjorde en anteckning för mig själv att skriva en artikel om thm. När jag kom tillbaka för att faktiskt starta den här artikeln, med exakt samma fråga på exakt samma virtuella dator, kunde jag inte generera en verklig exekveringsplan som innehöll UdfElapsedTime- eller UdfCpuTime-informationen trots upprepade försök. Jag kunde inte lista ut vad jag gjorde fel, och det visade sig att roten till problemet var att jag av misstag hade startat SQL Server Management Studio 2016 istället för SQL Server Management Studio 17.5. När jag körde samma fråga i SSMS 17.5 fick jag plötsligt tillbaka informationen UdfElapsedTime och UdfCpuTime. Se nedan för exempel på XML som returneras från båda SSMS-versionerna:
Visa plan för XML från SSMS 17,5
Visa plan för XML från SSMS 2016 – WaitStats och QueryTimeStats har tagits bort helt
Jag använde Microsoft Message Analyzer för att producera ett TCP-spår av nätverkstrafik på port 1433 mellan en klient som kör SSMS 2016 mot en SQL Server 2016 SP2-instans för att fånga TDS-paketen som skickas från servern till klienten. Detta avslöjar att ShowPlanXML som returnerades av servern inkluderade QueryTimeStats-informationen även om den inte visas i ShowPlanXML i SSMS 2016, så klienten tar faktiskt bort alla fält som inte ingår i schemadefinitionen som levererades med klienten.
Meddelandeoffset:1635
<.Q.u.e.r.y.T.i.m.e.S.t.a.t.s. .E.l.a.p.s.e.d.T.i.m.e.=.".2.6.7.". .C.p.u.T.i.m.e.=.".2.6.7.". .U.d.f.E.l.a.p.s.e.d.T.i.m.e.=.".2.1.5.". .U.d.f.C.p.u.T.i.m.e.=.".2.1.5.".>.<./.Q.u.e.r.y.T.i.m.e.S.t.a.t.s.>
Detta är något att se upp med med .sqlplan-filer som genereras med hjälp av äldre klientversioner av SSMS och/eller exekveringsplaner som sparas eller kopieras från en äldre version av SSMS, vilket är något som ofta händer när jag arbetar med klienter av e-post.
I SSMS ger inte en titt på den grafiska exekveringsplanen dig någon indikation på prestandan av den skalära användardefinierade funktionsexekveringen i frågan:
Om vi baserat vår analys av prestandan strikt på kostnaderna för varje operatör, ser Compute Scalar för funktionsutförandet inte ut som en betydande inverkan på prestandan. Verktygstipsen för operatörerna materialiserar inte heller informationen eller innehåller några varningar om effekten av den användardefinierade funktionen. Det enda stället vi ser informationen inom SSMS för närvarande är i planens XML, eller i egenskapsfönstret för SELECT-rotoperatorn för planen, som visas nedan:
Med hjälp av informationen här kan vi dock se att UdfCpuTime är 85,79% av den totala CpuTime och UdfElapsedTime är 64,44% av den totala ElapsedTime för frågans exekvering (som gör matten för att beräkna procentsatserna med QueryTimeStats CpuTime och UdghCpuTime (hi blå ovan), och förfluten tid och Udf förfluten tid).
Använda SentryOne Plan Explorer för att hämta planer
Ett av mina favoritgratisverktyg för att hjälpa till med prestandajustering av SQL Server är SentryOne Plan Explorer, och en av funktionerna i Plan Explorer under lång tid har varit möjligheten att skapa en verklig exekveringsplan genom att klistra in kommandotexten i ett nytt fönster och klicka på knappen Få faktisk plan, som visas nedan.
Eftersom Plan Explorer läser ShowplanXML som den tillhandahålls av SQL Server-motorn, kommer den också att innehålla den förbättrade informationen i QueryTimeStats. Men om du öppnar en exekveringsplan som sparades från en äldre version av Management Studio, eller om du använder Plan Explorer-tillägget för SSMS i en äldre version för att se planen i Plan Explorer, kommer den förbättrade informationen inte att visas.
Uttalandet på fliken Resultat i Plan Explorer kan uppdateras med kolumnväljaren för att lägga till kolumnerna UDF Duration och UDF CPU tillsammans med de befintliga kolumnerna i rutnätet, vilket gör det enkelt att se var användardefinierad funktionsexekvering påverkar för stora partier med flera uttalanden. Plan Explorer ger också framhävning av dessa kolumner när de är en betydande del av den totala CPU:n och/eller varaktigheten som visas nedan.
Plandiagraminformationen i Plan Explorer har också förbättrats. Här är diagrammen med Costs by CPU + I/O och sedan Costs by CPU:
Planera diagram med hjälp av kostnader med CPU + I/O
Planera diagram med hjälp av kostnader av CPU
Det finns ytterligare varningar på root SELECT-operatorn när exekveringsstatistiken för användardefinierade funktioner indikerar att de är en betydande del av den totala CPU:n och/eller den totala varaktigheten:
Verktygstips för roten SELECT operator
Compute Scalar-operatören har också en varning i Plan Explorer baserat på radantalet som bearbetas av operationen, även för planer som inte inkluderar förbättringarna för ShowplanXML:
Verktygstips för beräkningen Skalär operator
Att visa kostnader per CPU kan hjälpa till att identifiera operatörer med dolda CPU-kostnader som kan drunkna i I/O. Denna förmåga att ändra vyn något för att felsöka antingen CPU eller I/O på egen hand är en av de många skillnaderna mellan Plan Explorer och SSMS. Här är diagrammets snabbmeny där du kan ändra denna vy:
Slutsats
Förbättringarna av Showplan XML i SQL Server gör det mycket lättare att bestämma den övergripande effekten av skalära användardefinierade funktioner på frågeprestanda i SQL Server 2016 Service Pack 2 och SQL Server 2017 Cumulative Update 3, så länge du använder en mer senaste versionen av klientverktygen eller Plan Explorer för att hämta exekveringsplanen.