Est-ce que SQL Sentry Plan Explorer compte les lectures dans les FDU?

9

J'ai une requête comme celle-ci:

select dbo.fn_complexFunction(t.id)
from mytable t

Dans SQL Sentry Plan Explorer, j'ai remarqué que je devais exécuter Get Estimated Plan dans SQL Sentry pour que le plan de requête inclue l'UDF.

Lors de l'exécution de «Get Actual Plan», il ne semble pas que les lectures logiques et autres mesures incluent les opérations qui se produisent dans l'UDF. Dans des cas comme celui-ci, est-ce la seule solution de contournement pour utiliser le profileur?

Gabe
la source
1
À ma connaissance, le moteur de requête lui-même ne prend pas en compte les lectures dans les FDU. C'est une grande raison pour laquelle les UDF sont bons à éviter, ils sont opaques pour l'optimiseur.
JNK

Réponses:

11

Clause de non-responsabilité évidente: je travaille pour SQL Sentry .

Les plus gros problèmes que nous avons sont:

  1. Comme le dit @JNK, SQL Server obscurcit l'utilisation d'un UDF et fait quand même des choses terribles avec eux (comme toujours estime une ligne). Lorsque vous générez un plan réel dans SSMS, vous ne voyez pas du tout son utilisation non plus. Nous sommes soumis aux mêmes limitations car nous ne pouvons fournir que les informations sur un plan que SQL Server nous fournit.
  2. Nous comptons sur différentes sources pour les mesures d'exécution lors de la génération d'un plan réel. Malheureusement, le plan XML n'inclut pas d'appels de fonction, et SQL Server ne révèle pas les E / S encourues par une fonction lors de l'utilisation de l'une SET STATISTICS IO ON;ou l'autre (c'est ainsi que nous remplissons notre Table I/Oonglet).

Considérez la vue et la fonction suivantes par rapport à AdventureWorks2012. C'est juste une tentative idiote de renvoyer une ligne aléatoire de la table de détail étant donné une ligne aléatoire de la table d'en-tête - principalement pour nous assurer que nous générons autant d'E / S que possible, à chaque fois.

CREATE VIEW dbo.myview 
WITH SCHEMABINDING
AS
  SELECT TOP (100000) rowguid, SalesOrderID, n = NEWID() 
    FROM Sales.SalesOrderDetail ORDER BY NEWID();
GO

CREATE FUNCTION dbo.whatever(@SalesOrderID INT)
RETURNS UNIQUEIDENTIFIER
WITH SCHEMABINDING
AS
BEGIN
  RETURN 
  (
    SELECT TOP (1) rowguid FROM dbo.myview 
     WHERE SalesOrderID = @SalesOrderID ORDER BY n
  );
END
GO

Ce que Management Studio vous dit (et ne dit pas)

Prenez la requête suivante dans SSMS:

SET STATISTICS IO ON;

  SELECT TOP (5) SalesOrderID, dbo.whatever(SalesOrderID) 
    FROM Sales.SalesOrderHeader ORDER BY NEWID();

SET STATISTICS IO OFF;

Lorsque vous estimez un plan, vous obtenez un plan pour la requête et un plan unique pour la fonction (pas 5, comme vous pouvez l'espérer):

Plan estimé dans Management Studio

De toute évidence, vous n'obtenez aucune donnée d'E / S, car la requête n'a pas été réellement exécutée. Maintenant, générez un plan réel. Vous obtenez les 5 lignes que vous attendiez dans la grille de résultats, le plan suivant (qui ne fait absolument aucune mention visible de l'UDF, sauf que dans le XML, vous pouvez le trouver dans le texte de la requête et dans le cadre de l'opérateur scalaire):

Plan réel dans Management Studio

Et la STATISTICS IOsortie suivante (qui ne fait absolument aucune mention Sales.SalesOrderDetail, même si nous savons qu'elle doit être lue à partir de ce tableau):

Tableau 'SalesOrderHeader'. Nombre de balayages 1, lectures logiques 57, lectures physiques 0, lectures anticipées 0, lectures logiques 0, lob lectures physiques 0, lob lectures anticipées 0.

Ce que Plan Explorer vous dit

Lorsque nous générons un plan estimé pour la même requête, nous savons la même chose que SSMS. Cependant, nous montrons les choses d'une manière légèrement plus intuitive. Par exemple, le plan estimé pour la requête externe montre comment la sortie de la fonction est combinée avec la sortie de la requête, et il est immédiatement clair - dans un diagramme de plan unique - qu'il y a des E / S des deux tables :

Plan estimé dans Plan Explorer

Nous montrons également le plan de la fonction lui - même , que j'inclus uniquement pour être complet:

Plan estimé pour UDF dans Plan Explorer

Maintenant, jetons un coup d'œil à un plan réel, qui est des milliers de fois plus utile. L'inconvénient ici est, encore une fois, que nous ne disposons que des informations que SQL Server décide d'afficher, nous ne pouvons donc exposer que les diagrammes de plan graphique que SQL Server nous donne. Ce n'est pas une situation où nous avons décidé de ne pas vous montrer quelque chose d'utile; nous n'en savons rien sur la base du plan XML qui nous est fourni. Dans ce cas, c'est comme dans SSMS, nous ne voyons que le plan de la requête externe, et c'est comme si la fonction n'était pas du tout appelée :

Plan réel dans Plan Explorer

Notre onglet Table I / O, également, repose toujours sur la sortie deSTATISTICS IO , qui ignore également toute activité effectuée dans l'appel de fonction:

E / S de table pour le plan réel dans Plan Explorer

Cependant, nous obtenons toute la pile d'appels pour vous. J'ai parfois entendu des gens demander: "Pffft, quand aurai-je besoin de la pile d'appels?" Nous pouvons réellement décomposer le temps passé, le processeur utilisé et le nombre de lectures (et, pour les TVF, le nombre de lignes produites) pour chaque appel de fonction :

Pile d'appels dans Plan Explorer, affichant les appels UDF

Malheureusement, nous n'avons pas la possibilité de corréler cela à la ou aux tables d'où proviennent les E / S (encore une fois, car SQL Server ne nous donne pas ces informations), et il n'est pas étiqueté avec le nom UDF (car il est capturé en tant qu'instruction ad hoc, pas l'appel de fonction lui-même). Mais ce que cela vous permet de voir, ce que Management Studio ne fait pas, c'est ce qu'est votre chien. Vous devez encore joindre certains points, mais il y a moins de points et ils sont plus proches les uns des autres.

À propos de Profiler

Enfin, je recommanderais fortement de rester à l'écart de Profiler, sauf si c'est pour configurer une trace côté serveur que vous allez exécuter en dehors de la portée de tout outil d'interface utilisateur. L'utilisation de Profiler contre un système de production va certainement causer plus de problèmes qu'elle n'en résoudra jamais . Si vous souhaitez obtenir ces informations, veuillez utiliser une trace côté serveur ou des événements étendus, et assurez-vous de filtrer très judicieusement. Même sans profileur, une trace peut avoir un impact sur votre serveur, et la récupération de plans d'exécution via des événements étendus n'est pas non plus la chose la plus efficace au monde .

Aaron Bertrand
la source
Ah, je ne connaissais pas la pile d'appels dans la version Pro. C'est exactement ce que je cherchais. C'est bon de savoir que ça existe. À ce stade, je ne pense pas pouvoir justifier le prix, mais je le garderai à l'esprit pour les situations futures. Y a-t-il une raison pour laquelle SQL Server ne fournit pas d'informations d'E / S pour les FDU dans STATISTICS IO? Il est trompeur d'omettre ces informations essentielles.
Gabe
3
@Gabe Je ne connais pas la raison, désolé. Peut-être pour rendre le conseil plus lucratif?
Aaron Bertrand
1
@gabe maintenant l'explorateur de plans est complètement gratuit .. son appelé sentinelle qui a toutes les fonctionnalités de l'édition pro + ultime - toutes gratuites.
Kin Shah