Geschätzter versus tatsächlicher Abfrageplan mit Funktionsaufrufen

11

Ich habe diese Abfrage auf SQL Server, eine Zusammenführungsreplikationsabfrage:

SELECT DISTINCT
    b.tablenick,
    b.rowguid,
    c.generation,
    sys.fn_MSgeneration_downloadonly
    (
        c.generation,
        c.tablenick
    )
FROM #belong b
LEFT OUTER JOIN dbo.MSmerge_contents c ON 
    c.tablenick = b.tablenick
    AND c.rowguid = b.rowguid;

Der geschätzte Abfrageplan enthält Informationen zu 3 Abfragen:

  1. Die obige Abfrage
  2. Der Funktionsaufruf nur für fn_MSgeneration_download
  3. Der Funktionsaufruf von fn_MSArticle_has_downloadonly_property

Der eigentliche Abfrageplan enthält nur die folgenden Informationen:

  1. Die obige Abfrage

Nichts über die Funktionen. Warum fehlen die Funktionsinformationen im aktuellen Plan?

Ich habe folgende Optionen ausprobiert:

SET STATISTICS PROFILE ON
SET STATISTICS XML ON

Dadurch wurde ein tatsächlicher Plan erstellt, aber es fehlten die Teile 2 und 3 genauso wie bei der Verwendung der Option für den tatsächlichen Abfrageplan in Management Studio.

Wenn ich beispielsweise Profiler verwenden würde, um die Informationen zu den Funktionsaufrufen zu erfassen, welche Ereignisse würde ich auswählen?


Ich habe keine Antwort speziell für die Abfragepläne gefunden, aber ich habe SP: StmtStarting und SP: StmtCompleted profiliert und die Funktionsaufrufe angezeigt.

Peter
quelle

Antworten:

17

Und nichts über die Funktionen. Warum fehlen die Funktionsinformationen im aktuellen Plan?

Dies ist aus Leistungsgründen beabsichtigt.

Funktionen, die BEGINund ENDin der Definition enthalten sind, erstellen für jede Eingabezeile einen neuen T-SQL-Stapelrahmen. Anders ausgedrückt, der Funktionskörper wird für jede Eingabezeile separat ausgeführt . Diese einzige Tatsache erklärt die meisten Leistungsprobleme, die mit T-SQL-Skalar- und Multi-Anweisungsfunktionen verbunden sind (beachten Sie, dass Inline-Tabellenwertfunktionen nicht die BEGIN...ENDSyntax verwenden).

Im Kontext Ihrer Frage würde dies zu einer vollständigen SHOWPLANAusgabe für jede Zeile führen. Die Ausgabe von XML-Plänen ist recht ausführlich und teuer in der Erstellung. Daher wäre es im Allgemeinen eine schlechte Idee, für jede Zeile eine vollständige Ausgabe zu erstellen.

Beispiel

Betrachten Sie die folgende T-SQL-Skalarfunktion, die in der AdventureWorks- Beispieldatenbank erstellt wurde und den Namen eines Produkts mit seiner ID zurückgibt:

CREATE FUNCTION dbo.DumbNameLookup
(
    @ProductID integer
)
RETURNS dbo.Name
AS
BEGIN
    RETURN
    (
        SELECT
            p.Name
        FROM Production.Product AS p
        WHERE
            p.ProductID = @ProductID
    );
END;

Plan vor der Ausführung

Ein Pre-Execution-Plan (geschätzter Plan in SSMS) zeigt Planinformationen für die übergeordnete Anweisung und verschachtelte Funktionsaufrufe an:

-- Pre-execution plan shows main query and nested function call
SET SHOWPLAN_XML ON;
GO
SELECT dbo.DumbNameLookup(1);
GO
SET SHOWPLAN_XML OFF;

SSMS-Ausgabe:

SSMS-Vorausführungsplan

Dasselbe XML, das im SQL Sentry Plan Explorer angezeigt wird, zeigt die Verschachtelung der Aufrufe deutlicher:

PE-Vorabausführungsplan

Ausgabe nach der Ausführung

SSMS zeigt Details nur für die Hauptabfrage an, wenn die Ausgabe des Plans nach der Ausführung angefordert wird:

-- Post-execution plan shows main query only
SET STATISTICS XML ON;
SELECT dbo.DumbNameLookup(1);
SET STATISTICS XML OFF;

SSMS-Nachausführung

Die Auswirkungen eines anderen Vorgehens auf die Leistung können mithilfe der Ereignisklasse Showplan XML Statistics Profile in SQL Server Profiler mithilfe einer Abfrage angezeigt werden , die die Funktion mehrmals aufruft (einmal pro Eingabezeile):

SELECT TOP (5)
    p.ProductID,
    dbo.DumbNameLookup(p.ProductID)
FROM Production.Product AS p;

Profiler-Ausgabe:

Trace-Ausgabe

Es gibt fünf separate Nachausführungspläne für die Funktionsausführungen und einen für die übergeordnete Abfrage. Die fünf Funktionspläne sehen im unteren Bereich des Profilers folgendermaßen aus:

Funktionspläne

Der übergeordnete Abfrageplan lautet:

Elternplan

Das Ausführen der Abfrage ohne die TOP (5)Klausel führt zu einem vollständigen Ausführungsplan für jede der 504 Zeilen in der Produkttabelle. Sie können wahrscheinlich sehen, wie dies bei größeren Tischen schnell außer Kontrolle geraten würde.

Die Situation für Trigger ist umgekehrt. Diese zeigen keine Informationen zum Plan vor der Ausführung an, enthalten jedoch einen Plan nach der Ausführung. Dies spiegelt die satzbasierte Natur von Triggern wider. Jedes wird einmal für alle betroffenen Zeilen und nicht einmal pro Zeile ausgelöst.

Paul White 9
quelle
@PaulWhite gibt es einen guten Grund, warum Triggerpläne nicht angezeigt werden, wenn der geschätzte Ausführungsplan angefordert wird? Das scheint eine nützliche fehlende Funktion zu sein. Ich könnte ein Verbindungselement dafür erstellen.
usr
@usr - Vielleicht, weil der tatsächlich ausgewählte zwischengespeicherte Plan abhängig von der tatsächlichen Anzahl der hier beschriebenen Zeilen variieren kann? technet.microsoft.com/en-us/library/…
Martin Smith
@ MartinSmith das könnte ein Grund sein. Kürzlich wurde ein Verbindungselement für Ausführungspläne von Prüf- und fk-Einschränkungen als abgeschlossen markiert, sodass ich hoffte, dass sie dasselbe mit Triggern tun würden.
usr
@usr - Dieser hier ? 3 Monate? Das muss ein Rekord für eine neue Feature-Anfrage sein!
Martin Smith
@ MartinSmith ja, das hier. Es wurde vor 1-2 "repariert". Ich hoffe wirklich, dass ich den Abfragespeicher nicht abfragen muss. Ich hatte gehofft, in SSMS auf eine Schaltfläche zu klicken. Eigentlich war ich überrascht, dass sich an einem Teil des Motors, der seit Jahren nicht mehr berührt wurde, überhaupt etwas geändert hat. Aber vielleicht gab es keine.
usr