Microsoft a amélioré le contenu de la sortie ShowplanXML pour SQL Server au cours des dernières versions et dans SQL Server 2017 CU3, ils ont introduit des statistiques d'exécution de fonctions définies par l'utilisateur (UDF) dans le nœud QueryTimeStats de la sortie XML. Cela a également été rétroporté vers SQL Server 2016 dans le Service Pack 2 pour les plans d'exécution réels. Cette fonctionnalité vous permet de connaître définitivement l'impact de l'exécution UDF scalaire dans le cadre des caractéristiques de performance d'une requête. Cependant, il y a un hic intéressant associé à l'utilisation de cette fonctionnalité; vous devez collecter le plan d'exécution réel à l'aide d'une version à jour de SQL Server Management Studio ou à l'aide de SentryOne Plan Explorer, sinon les informations seront supprimées du plan d'exécution.
Comparaison des plans dans différentes versions de SSMS
J'ai récemment présenté une session de groupe d'utilisateurs à Chicago sur le réglage des performances des requêtes à l'aide du cache de plan et pendant la session, j'utilisais la dernière version de SQL Server Management Studio à l'époque, la version 17.5. À l'époque, j'avais également récemment mis à jour ma machine virtuelle vers SQL Server 2016 Service Pack 2, j'ai donc démontré les nouvelles informations UdfElapsedTime et UdfCpuTime dans le showplan QueryTimeStats et me suis fait une note pour écrire un article à ce sujet. Lorsque je suis revenu pour commencer cet article, en utilisant exactement la même requête sur la même machine virtuelle, je n'ai pas pu générer de plan d'exécution réel contenant les informations UdfElapsedTime ou UdfCpuTime malgré des tentatives répétées. Je ne pouvais pas comprendre ce que je faisais de mal, et il s'est avéré que la racine du problème était que j'avais accidentellement lancé SQL Server Management Studio 2016 au lieu de SQL Server Management Studio 17.5. Lorsque j'ai exécuté la même requête dans SSMS 17.5, j'ai soudainement récupéré les informations UdfElapsedTime et UdfCpuTime. Voir ci-dessous des exemples de XML renvoyés par les deux versions de SSMS :
Showplan XML de SSMS 17.5
Showplan XML de SSMS 2016 - WaitStats et QueryTimeStats ont été complètement supprimés
J'ai utilisé Microsoft Message Analyzer pour produire une trace TCP du trafic réseau sur le port 1433 entre un client exécutant SSMS 2016 et une instance SQL Server 2016 SP2 pour capturer les paquets TDS envoyés du serveur au client. Cela révèle que le ShowPlanXML renvoyé par le serveur incluait les informations QueryTimeStats même si elles n'apparaissent pas dans le ShowPlanXML dans SSMS 2016, de sorte que le client supprime en fait tous les champs non inclus dans la définition de schéma livrée avec le client.
Décalage de message :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.>
C'est quelque chose à surveiller avec les fichiers .sqlplan qui sont générés à l'aide d'anciennes versions client de SSMS et/ou de plans d'exécution qui sont enregistrés ou copiés à partir d'une ancienne version de SSMS, ce qui arrive souvent lorsque je travaille avec des clients par e-mail.
Dans SSMS, l'examen du plan d'exécution graphique ne vous donne aucune indication sur l'impact sur les performances de l'exécution de la fonction scalaire définie par l'utilisateur dans la requête :
Si nous basons notre analyse des performances strictement sur les coûts de chaque opérateur, le Compute Scalar pour l'exécution de la fonction ne semble pas avoir un impact significatif sur les performances. Les info-bulles pour les opérateurs ne matérialisent pas non plus les informations ou ne contiennent aucun avertissement sur l'impact de la fonction définie par l'utilisateur. Le seul endroit où nous voyons ces informations dans SSMS actuellement se trouve dans le XML du plan, ou dans la fenêtre Propriétés pour l'opérateur racine SELECT du plan, comme indiqué ci-dessous :
En utilisant les informations ici cependant, nous pouvons voir que le UdfCpuTime est de 85,79 % du total CpuTime et le UdfElapsedTime est de 64,44 % du total ElapsedTime pour l'exécution de la requête (en faisant le calcul pour calculer les pourcentages à l'aide de QueryTimeStats CpuTime et UdfCpuTime (mis en évidence dans bleu ci-dessus), et ElapsedTime et UdfElapsedTime).
Utilisation de SentryOne Plan Explorer pour récupérer des plans
L'un de mes outils gratuits préférés pour aider à l'optimisation des performances de SQL Server est SentryOne Plan Explorer, et l'une des fonctionnalités de Plan Explorer depuis longtemps a été la possibilité de générer un plan d'exécution réel en collant le texte de la commande dans une nouvelle fenêtre et en cliquant sur le bouton Obtenir le plan réel, comme indiqué ci-dessous.
Étant donné que Plan Explorer lit le ShowplanXML tel qu'il est fourni par le moteur SQL Server, il contiendra également les informations améliorées dans QueryTimeStats. Toutefois, si vous ouvrez un plan d'exécution qui a été enregistré à partir d'une version antérieure de Management Studio, ou si vous utilisez le complément Plan Explorer pour SSMS dans une version antérieure pour afficher le plan dans Plan Explorer, les informations améliorées ne s'afficheront pas.
La grille de déclaration de l'onglet Résultats dans Plan Explorer peut être mise à jour à l'aide du sélecteur de colonne pour ajouter les colonnes UDF Duration et UDF CPU avec les colonnes existantes dans la grille, ce qui permet de voir facilement où l'exécution de la fonction définie par l'utilisateur a un impact. pour les grands lots multi-instructions. Plan Explorer fournit également la mise en surbrillance de ces colonnes lorsqu'elles représentent une partie importante de l'UC globale et/ou de la durée, comme indiqué ci-dessous.
Les informations du diagramme de plan dans Plan Explorer ont également été améliorées. Voici les schémas utilisant Coûts par CPU + E/S puis Coûts par CPU :
Planifier le diagramme à l'aide des coûts par CPU + E/S
Planifier le diagramme à l'aide des coûts par CPU
Il existe des avertissements supplémentaires sur l'opérateur racine SELECT lorsque les statistiques d'exécution des fonctions définies par l'utilisateur indiquent qu'elles représentent une partie importante du CPU global et/ou de la durée globale :
Info-bulle pour la racine Opérateur SELECT
L'opérateur Compute Scalar affiche également un avertissement dans Plan Explorer en fonction du nombre de lignes traitées par l'opération, même pour les plans qui n'incluent pas les améliorations pour ShowplanXML :
Info-bulle pour le calcul Opérateur scalaire
L'affichage des coûts par CPU peut aider à identifier les opérateurs avec des coûts CPU cachés qui pourraient être noyés par les E/S. Cette possibilité de déplacer légèrement la vue pour dépanner seul le processeur ou les E/S est l'un des nombreux différenciateurs entre Plan Explorer et SSMS. Voici le menu contextuel du diagramme où vous pouvez changer cette vue :
Conclusion
Les améliorations apportées à Showplan XML dans SQL Server facilitent grandement la détermination de l'impact global des fonctions scalaires définies par l'utilisateur sur les performances des requêtes dans SQL Server 2016 Service Pack 2 et SQL Server 2017 Cumulative Update 3, tant que vous utilisez une version plus version récente des outils clients ou Plan Explorer pour récupérer le plan d'exécution.