Zählt der SQL Sentry Plan Explorer die Lesevorgänge in UDFs?

9

Ich habe eine Frage wie diese:

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

Im SQL Sentry Plan Explorer ist mir aufgefallen, dass ich "Get Estimated Plan" in SQL Sentry ausführen muss, damit der Abfrageplan die UDF enthält.

Wenn Sie "Aktuellen Plan abrufen" ausführen, scheinen die logischen Lesevorgänge und andere Metriken nicht die Vorgänge zu enthalten, die in der UDF ausgeführt werden. Ist in solchen Fällen die einzige Problemumgehung, um den Profiler zu verwenden?

Gabe
quelle
1
Meines Wissens berücksichtigt die Abfrage-Engine selbst keine Lesevorgänge in UDFs. Dies ist ein wichtiger Grund, warum UDFs gut zu vermeiden sind und für den Optimierer undurchsichtig sind.
JNK

Antworten:

11

Offensichtlicher Haftungsausschluss: Ich arbeite für SQL Sentry .

Die größten Probleme, die wir haben, sind:

  1. Wie @JNK sagt, verschleiert SQL Server die Verwendung einer UDF und macht sowieso schreckliche Dinge mit ihnen (wie immer immer eine Zeile geschätzt). Wenn Sie einen tatsächlichen Plan in SSMS generieren, sehen Sie dessen Verwendung ebenfalls überhaupt nicht. Wir unterliegen denselben Einschränkungen, da wir nur die Informationen zu einem Plan bereitstellen können, den SQL Server uns zur Verfügung stellt.
  2. Bei der Erstellung eines tatsächlichen Plans stützen wir uns auf verschiedene Quellen für Laufzeitmetriken. Leider enthält das Plan-XML keine Funktionsaufrufe, und SQL Server zeigt nicht die E / A an, die bei der Verwendung einer Funktion anfallen SET STATISTICS IO ON;(auf diese Weise Table I/Ofüllen wir unsere Registerkarte).

Betrachten Sie die folgende Ansicht und Funktion für AdventureWorks2012. Dies ist nur ein dummer Versuch, eine zufällige Zeile aus der Detailtabelle zurückzugeben, wenn eine zufällige Zeile aus der Headertabelle stammt - hauptsächlich, um sicherzustellen, dass wir jedes Mal so viel E / A wie möglich generieren.

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

Was Management Studio Ihnen sagt (und was nicht)

Nehmen Sie die folgende Abfrage in SSMS vor:

SET STATISTICS IO ON;

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

SET STATISTICS IO OFF;

Wenn Sie einen Plan schätzen, erhalten Sie einen Plan für die Abfrage und einen einzelnen Plan für die Funktion (nicht 5, wie Sie vielleicht hoffen):

Geschätzter Plan in Management Studio

Sie erhalten offensichtlich überhaupt keine E / A-Daten, da die Abfrage nicht tatsächlich ausgeführt wurde. Generieren Sie nun einen aktuellen Plan. Sie erhalten die 5 Zeilen, die Sie im Ergebnisraster erwartet haben, den folgenden Plan (der die UDF absolut nicht sichtbar erwähnt, außer im XML finden Sie sie als Teil des Abfragetextes und als Teil des Skalaroperators):

Aktueller Plan in Management Studio

Und die folgende STATISTICS IOAusgabe (die absolut keine Erwähnung macht Sales.SalesOrderDetail, obwohl wir wissen , es hatte aus dieser Tabelle zu lesen):

Tabelle 'SalesOrderHeader'. Scananzahl 1, logische Lesevorgänge 57, physische Lesevorgänge 0, Vorauslesevorgänge 0, logische Vorlesevorgänge 0, physikalische Vorlesevorgänge 0, Vorlesevorgänge 0.

Was Plan Explorer Ihnen sagt

Wenn wir einen geschätzten Plan für dieselbe Abfrage erstellen, wissen wir über dasselbe Bescheid wie SSMS. Wir zeigen die Dinge jedoch etwas intuitiver. Der geschätzte Plan für die äußere Abfrage zeigt beispielsweise, wie die Ausgabe der Funktion mit der Ausgabe der Abfrage kombiniert wird, und es wird sofort - innerhalb eines einzelnen Plandiagramms - klar, dass E / A aus beiden Tabellen vorhanden sind :

Geschätzter Plan im Plan-Explorer

Wir zeigen auch den Funktionsplan für sich , den ich nur der Vollständigkeit halber einbeziehe:

Geschätzter Plan für UDF im Plan-Explorer

Schauen wir uns nun einen tatsächlichen Plan an, der tausendfach nützlicher ist. Der Nachteil hier ist wiederum, dass wir nur die Informationen haben, die SQL Server anzeigen möchte, sodass wir nur die grafischen Plandiagramme verfügbar machen können, die SQL Server uns zur Verfügung stellt. Dies ist keine Situation, in der wir beschlossen haben, Ihnen nichts Nützliches zu zeigen. Wir wissen eigentlich nichts darüber, basierend auf dem Plan-XML, das uns zur Verfügung gestellt wird. In diesem Fall sehen wir genau wie in SSMS nur den Plan der äußeren Abfrage und es ist, als ob die Funktion überhaupt nicht aufgerufen wird :

Aktueller Plan im Plan Explorer

Auch unsere Registerkarte "Tabellen-E / A" basiert weiterhin auf der Ausgabe vonSTATISTICS IO , wodurch auch alle im Funktionsaufruf ausgeführten Aktivitäten ignoriert werden:

Tabellen-E / A für den tatsächlichen Plan im Plan-Explorer

Wir erhalten jedoch den gesamten Call Stack für Sie. Ich habe gelegentlich Leute fragen hören: "Pffft, wann werde ich jemals den Call Stack brauchen?" Wir können die aufgewendete Zeit, die verwendete CPU und die Anzahl der Lesevorgänge (und bei TVFs die Anzahl der erzeugten Zeilen) für jeden einzelnen Funktionsaufruf aufschlüsseln :

Aufrufstapel im Plan-Explorer mit UDF-Aufrufen

Leider können wir nicht korrelieren, aus welcher Tabelle (n) die E / A stammt (wiederum, weil SQL Server uns diese Informationen nicht gibt), und sie ist nicht mit dem UDF-Namen gekennzeichnet (weil es als Ad-hoc-Anweisung erfasst wird, nicht als Funktionsaufruf selbst). Aber was Sie sehen können, was Management Studio nicht tut, ist, was für ein Hund Ihre UDF ist. Sie müssen noch einige Punkte verbinden, aber es gibt weniger Punkte und sie sind näher beieinander.

Über Profiler

Schließlich würde ich dringend empfehlen, sich von Profiler fernzuhalten, es sei denn, Sie möchten einen serverseitigen Trace einrichten, den Sie außerhalb des Bereichs eines UI-Tools ausführen. Die Verwendung von Profiler gegen ein Produktionssystem wird mit ziemlicher Sicherheit mehr Probleme verursachen, als es jemals lösen wird . Wenn Sie diese Informationen erhalten möchten, verwenden Sie bitte eine serverseitige Ablaufverfolgung oder erweiterte Ereignisse und filtern Sie sehr mit Bedacht. Selbst ohne Profiler kann sich eine Ablaufverfolgung auf Ihren Server auswirken, und das Abrufen von Showplänen über erweiterte Ereignisse ist auch nicht die effizienteste Sache der Welt .

Aaron Bertrand
quelle
Ah, ich wusste nichts über den Aufrufstapel in der Pro-Version. Genau das habe ich gesucht. Es ist gut zu wissen, dass es das gibt. Zum jetzigen Zeitpunkt glaube ich nicht, dass ich den Preis rechtfertigen kann, aber ich werde ihn für zukünftige Situationen berücksichtigen. Gibt es einen Grund, warum SQL Server keine E / A-Informationen für UDFs in STATISTICS IO bereitstellt? Es ist irreführend, solche wesentlichen Informationen wegzulassen.
Gabe
3
@Gabe Ich kenne den Grund nicht, sorry. Vielleicht, um die Beratung lukrativer zu gestalten?
Aaron Bertrand
1
@gabe now plan explorer ist völlig kostenlos. Es heißt sentry one und bietet alle Funktionen der Pro + Ultimate Edition - alles kostenlos.
Kin Shah