Wie erhalte ich einen Abfrageausführungsplan in SQL Server?

338

Wie kann ich in Microsoft SQL Server einen Ausführungsplan für eine Abfrage / gespeicherte Prozedur abrufen?

Justin
quelle
2
Wie schließe ich die Registerkarte Ausführungsplan in SQL Server Management Studio?
Paul McCarthy
2
@Paul Dafür kannst du Strg + R drücken. Es schließt den gesamten Ergebnisbereich - einschließlich der Nachrichten und des Ausführungsplans.
Nisarg

Antworten:

500

Es gibt eine Reihe von Methoden, um einen Ausführungsplan zu erhalten, die von Ihren Umständen abhängen. Normalerweise können Sie SQL Server Management Studio verwenden, um einen Plan abzurufen. Wenn Sie Ihre Abfrage jedoch aus irgendeinem Grund nicht in SQL Server Management Studio ausführen können, ist es möglicherweise hilfreich, einen Plan über SQL Server Profiler oder durch Überprüfen abzurufen der Plan-Cache.

Methode 1 - Verwenden von SQL Server Management Studio

SQL Server verfügt über einige nützliche Funktionen, mit denen Sie einen Ausführungsplan sehr einfach erfassen können. Stellen Sie einfach sicher, dass das Menüelement "Aktuellen Ausführungsplan einschließen" (im Menü "Abfrage" enthalten) aktiviert ist, und führen Sie Ihre Abfrage wie gewohnt aus .

Menüelement Aktionsausführungsplan einschließen

Wenn Sie versuchen, den Ausführungsplan für Anweisungen in einer gespeicherten Prozedur abzurufen, sollten Sie die gespeicherte Prozedur wie folgt ausführen:

exec p_Example 42

Wenn Ihre Abfrage abgeschlossen ist, sollte im Ergebnisbereich eine zusätzliche Registerkarte mit dem Titel "Ausführungsplan" angezeigt werden. Wenn Sie viele Anweisungen ausgeführt haben, werden möglicherweise viele Pläne auf dieser Registerkarte angezeigt.

Screenshot eines Ausführungsplans

Von hier aus können Sie den Ausführungsplan in SQL Server Management Studio überprüfen oder mit der rechten Maustaste auf den Plan klicken und "Ausführungsplan speichern unter ..." auswählen, um den Plan in einer Datei im XML-Format zu speichern.

Methode 2 - Verwenden von SHOWPLAN-Optionen

Diese Methode ist Methode 1 sehr ähnlich (tatsächlich ist dies das, was SQL Server Management Studio intern tut), ich habe sie jedoch der Vollständigkeit halber aufgenommen oder wenn Sie nicht über SQL Server Management Studio verfügen.

Führen Sie eine der folgenden Anweisungen aus, bevor Sie Ihre Abfrage ausführen . Die Anweisung muss die einzige Anweisung im Stapel sein, dh Sie können nicht gleichzeitig eine andere Anweisung ausführen:

SET SHOWPLAN_TEXT ON
SET SHOWPLAN_ALL ON
SET SHOWPLAN_XML ON
SET STATISTICS PROFILE ON
SET STATISTICS XML ON -- The is the recommended option to use

Dies sind Verbindungsoptionen, sodass Sie diese nur einmal pro Verbindung ausführen müssen. Ab diesem Zeitpunkt werden alle ausgeführten Anweisungen von einer zusätzlichen Ergebnismenge begleitet, die Ihren Ausführungsplan im gewünschten Format enthält. Führen Sie Ihre Abfrage einfach wie gewohnt aus , um den Plan anzuzeigen .

Sobald Sie fertig sind, können Sie diese Option mit der folgenden Anweisung deaktivieren:

SET <<option>> OFF

Vergleich der Ausführungsplanformate

Sofern Sie keine starke Präferenz haben, empfehle ich, die STATISTICS XMLOption zu verwenden. Diese Option entspricht der Option "Aktuellen Ausführungsplan einschließen" in SQL Server Management Studio und liefert die meisten Informationen im bequemsten Format.

  • SHOWPLAN_TEXT - Zeigt einen grundlegenden textbasierten geschätzten Ausführungsplan an, ohne die Abfrage auszuführen
  • SHOWPLAN_ALL - Zeigt einen textbasierten geschätzten Ausführungsplan mit Kostenschätzungen an, ohne die Abfrage auszuführen
  • SHOWPLAN_XML- Zeigt einen XML-basierten geschätzten Ausführungsplan mit Kostenschätzungen an, ohne die Abfrage auszuführen. Dies entspricht der Option "Geschätzten Ausführungsplan anzeigen ..." in SQL Server Management Studio.
  • STATISTICS PROFILE - Führt die Abfrage aus und zeigt einen textbasierten tatsächlichen Ausführungsplan an.
  • STATISTICS XML- Führt die Abfrage aus und zeigt einen XML-basierten tatsächlichen Ausführungsplan an. Dies entspricht der Option "Aktuellen Ausführungsplan einschließen" in SQL Server Management Studio.

Methode 3 - Verwenden von SQL Server Profiler

Wenn Sie Ihre Abfrage nicht direkt ausführen können (oder wenn Ihre Abfrage nicht direkt ausgeführt wird, wenn Sie sie direkt ausführen - denken Sie daran, dass ein Plan für die Abfrage schlecht ausgeführt werden soll), können Sie einen Plan mithilfe eines SQL Server Profiler-Trace erfassen. Die Idee ist, Ihre Abfrage auszuführen, während ein Trace ausgeführt wird, der eines der "Showplan" -Ereignisse erfasst.

Beachten Sie, dass je nach Last Sie können diese Methode auf einer Produktionsumgebung verwenden, aber Sie sollten offensichtlich Vorsicht walten lassen. Die SQL Server Profilierungsmechanismen sind so konzipiert , Auswirkungen auf die Datenbank zu minimieren , aber dies bedeutet nicht , dass es nicht irgendwelche Auswirkungen auf die Leistung. Möglicherweise haben Sie auch Probleme beim Filtern und Identifizieren des richtigen Plans in Ihrer Ablaufverfolgung, wenn Ihre Datenbank stark beansprucht wird. Sie sollten sich natürlich bei Ihrem DBA erkundigen, ob er mit Ihnen in seiner wertvollen Datenbank zufrieden ist!

  1. Öffnen Sie den SQL Server Profiler und erstellen Sie eine neue Ablaufverfolgung, die eine Verbindung zur gewünschten Datenbank herstellt, für die Sie die Ablaufverfolgung aufzeichnen möchten.
  2. Aktivieren Sie auf der Registerkarte "Ereignisauswahl" die Option "Alle Ereignisse anzeigen", überprüfen Sie die Zeile "Leistung" -> "XML anzeigen" und führen Sie den Trace aus.
  3. Führen Sie während der Ausführung des Trace alles aus, was Sie tun müssen, damit die langsam laufende Abfrage ausgeführt wird.
  4. Warten Sie, bis die Abfrage abgeschlossen ist, und stoppen Sie die Ablaufverfolgung.
  5. Um die Ablaufverfolgung zu speichern, klicken Sie im SQL Server Profiler mit der rechten Maustaste auf die Plan-XML und wählen Sie "Ereignisdaten extrahieren ...", um den Plan in einer Datei im XML-Format zu speichern.

Der Plan, den Sie erhalten, entspricht der Option "Aktuellen Ausführungsplan einschließen" in SQL Server Management Studio.

Methode 4 - Überprüfen des Abfragecaches

Wenn Sie Ihre Abfrage nicht direkt ausführen können und auch keinen Profiler-Trace erfassen können, können Sie dennoch einen geschätzten Plan erhalten, indem Sie den SQL-Abfrageplan-Cache überprüfen.

Wir überprüfen den Plan-Cache, indem wir SQL Server- DMVs abfragen . Im Folgenden finden Sie eine grundlegende Abfrage, in der alle zwischengespeicherten Abfragepläne (als XML) zusammen mit ihrem SQL-Text aufgelistet werden. In den meisten Datenbanken müssen Sie außerdem zusätzliche Filterklauseln hinzufügen, um die Ergebnisse auf die Pläne zu filtern, an denen Sie interessiert sind.

SELECT UseCounts, Cacheobjtype, Objtype, TEXT, query_plan
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
CROSS APPLY sys.dm_exec_query_plan(plan_handle)

Führen Sie diese Abfrage aus und klicken Sie auf das Plan-XML, um den Plan in einem neuen Fenster zu öffnen. Klicken Sie mit der rechten Maustaste und wählen Sie "Ausführungsplan speichern unter ...", um den Plan in einer Datei im XML-Format zu speichern.

Anmerkungen:

Da es so viele Faktoren gibt (von der Tabelle und dem Indexschema bis zu den gespeicherten Daten und den Tabellenstatistiken), sollten Sie immer versuchen, einen Ausführungsplan aus der Datenbank zu erhalten, an der Sie interessiert sind (normalerweise diejenige, bei der eine Leistung auftritt Problem).

Sie können keinen Ausführungsplan für verschlüsselte gespeicherte Prozeduren erfassen.

"tatsächliche" vs "geschätzte" Ausführungspläne

Ein tatsächlicher Ausführungsplan ist einer, bei dem SQL Server die Abfrage tatsächlich ausführt , während ein geschätzter Ausführungsplan SQL Server herausfindet, was er ohne Ausführung der Abfrage tun würde . Obwohl logisch äquivalent, ist ein tatsächlicher Ausführungsplan viel nützlicher, da er zusätzliche Details und Statistiken darüber enthält, was bei der Ausführung der Abfrage tatsächlich passiert ist. Dies ist wichtig, wenn Sie Probleme diagnostizieren, bei denen die Schätzungen von SQL Servern nicht korrekt sind (z. B. wenn Statistiken nicht mehr aktuell sind).

Wie interpretiere ich einen Abfrageausführungsplan?

Dies ist ein Thema, das für ein (kostenloses) Buch an sich würdig genug ist .

Siehe auch:

Justin
quelle
8
Ein Hinweis für zukünftige Leser: SET STATISTICS XML ONSetzen Sie den Anfang der Abfrage und die SET STATISTICS XML OFF|ONumgebenden Bereiche, die nicht in der Planausgabe angezeigt werden sollen: Ich fand dies nützlich, wenn die Abfrage eine Iteration (WHILE) enthält, die Sie nicht möchten / benötigen im Ausführungsplan zu sehen (sonst wäre es zu schwer und zu lang für SQL Server, um es anzuzeigen).
Roimer
2
@MonsterMMORPG Sie können Methode 4 verwenden und dann SELECT. Verwenden Sie beispielsweise <a href=" github.com/StackExchange/dapper-dot-net"> Dapper.net </… > connection.Query <string> ("SELECT query_plan FROM sys.dm_exec_cached_plans CROSS APPLY sys.dm_exec_sql_text (plan_handle) ) CROSS APPLY sys.dm_exec_query_plan (plan_handle) WO TEXT WIE N '% Ihre ursprüngliche Abfrage geht hierher%' "); Die% sind, wenn Sie nur eine Teilmenge Ihrer Abfrage verwenden.
Bmarks
2
@Justin Die 2. Ausgabe des Buches, auf das Sie zur Interpretation eines Abfrageausführungsplans verlinkt haben, stammt aus dem Jahr 2009. Würden Sie immer noch sagen, dass es 2016 eine wirklich gute Ressource für diesen Zweck ist?
Abdul
3
@Abdul Der gleiche Autor, Grant Fritchey, hat ein neueres Buch namens SQL Server Query Performance Tuning, das neuere Versionen von SQL Server behandelt.
Thelem
42

Zusätzlich zu der bereits veröffentlichten umfassenden Antwort ist es manchmal nützlich, programmgesteuert auf den Ausführungsplan zugreifen zu können, um Informationen zu extrahieren. Beispielcode dafür ist unten.

DECLARE @TraceID INT
EXEC StartCapture @@SPID, @TraceID OUTPUT
EXEC sp_help 'sys.objects' /*<-- Call your stored proc of interest here.*/
EXEC StopCapture @TraceID

Beispiel StartCaptureDefinition

CREATE PROCEDURE StartCapture
@Spid INT,
@TraceID INT OUTPUT
AS
DECLARE @maxfilesize BIGINT = 5
DECLARE @filepath NVARCHAR(200) = N'C:\trace_' + LEFT(NEWID(),36)

EXEC sp_trace_create @TraceID OUTPUT, 0, @filepath, @maxfilesize, NULL 

exec sp_trace_setevent @TraceID, 122, 1, 1
exec sp_trace_setevent @TraceID, 122, 22, 1
exec sp_trace_setevent @TraceID, 122, 34, 1
exec sp_trace_setevent @TraceID, 122, 51, 1
exec sp_trace_setevent @TraceID, 122, 12, 1
-- filter for spid
EXEC sp_trace_setfilter @TraceID, 12, 0, 0, @Spid
-- start the trace
EXEC sp_trace_setstatus @TraceID, 1

Beispiel StopCaptureDefinition

CREATE  PROCEDURE StopCapture
@TraceID INT
AS
WITH  XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' as sql), 
      CTE
     as (SELECT CAST(TextData AS VARCHAR(MAX)) AS TextData,
                ObjectID,
                ObjectName,
                EventSequence,
                /*costs accumulate up the tree so the MAX should be the root*/
                MAX(EstimatedTotalSubtreeCost) AS EstimatedTotalSubtreeCost
         FROM   fn_trace_getinfo(@TraceID) fn
                CROSS APPLY fn_trace_gettable(CAST(value AS NVARCHAR(200)), 1)
                CROSS APPLY (SELECT CAST(TextData AS XML) AS xPlan) x
                CROSS APPLY (SELECT T.relop.value('@EstimatedTotalSubtreeCost',
                                            'float') AS EstimatedTotalSubtreeCost
                             FROM   xPlan.nodes('//sql:RelOp') T(relop)) ca
         WHERE  property = 2
                AND TextData IS NOT NULL
                AND ObjectName not in ( 'StopCapture', 'fn_trace_getinfo' )
         GROUP  BY CAST(TextData AS VARCHAR(MAX)),
                   ObjectID,
                   ObjectName,
                   EventSequence)
SELECT ObjectName,
       SUM(EstimatedTotalSubtreeCost) AS EstimatedTotalSubtreeCost
FROM   CTE
GROUP  BY ObjectID,
          ObjectName  

-- Stop the trace
EXEC sp_trace_setstatus @TraceID, 0
-- Close and delete the trace
EXEC sp_trace_setstatus @TraceID, 2
GO
Martin Smith
quelle
18

Angenommen, Sie verwenden Microsoft SQL Server Management Studio

  • Für den geschätzten Abfrageplan können Sie Strg + L oder die folgende Schaltfläche drücken.

Geben Sie hier die Bildbeschreibung ein

  • Für den tatsächlichen Abfrageplan können Sie Strg + M oder die folgende Schaltfläche drücken, bevor Sie die Abfrage ausführen.

Geben Sie hier die Bildbeschreibung ein

  • Verwenden Sie für Live Query Plan (nur in SSMS 2016) die folgende Schaltfläche, bevor Sie die Abfrage ausführen.

Geben Sie hier die Bildbeschreibung ein

Tigerjz32
quelle
15

Neben den in den vorherigen Antworten beschriebenen Methoden können Sie auch einen kostenlosen Ausführungsplan-Viewer und ein Abfrageoptimierungstool ApexSQL Plan verwenden (auf das ich kürzlich gestoßen bin).

Sie können ApexSQL Plan installieren und in SQL Server Management Studio integrieren, sodass Ausführungspläne direkt von SSMS aus angezeigt werden können.

Anzeigen der geschätzten Ausführungspläne in ApexSQL Plan

  1. Klicken Sie in SSMS auf die Schaltfläche Neue Abfrage und fügen Sie den Abfragetext in das Abfragetextfenster ein. Klicken Sie mit der rechten Maustaste und wählen Sie im Kontextmenü die Option "Geschätzten Ausführungsplan anzeigen".

Neue Abfrage-Schaltfläche in SSMS

  1. Die Ausführungsplandiagramme werden auf der Registerkarte Ausführungsplan im Ergebnisbereich angezeigt. Klicken Sie anschließend mit der rechten Maustaste auf den Ausführungsplan und wählen Sie im Kontextmenü die Option "In ApexSQL-Plan öffnen".

Ausführungsplan

  1. Der geschätzte Ausführungsplan wird in ApexSQL Plan geöffnet und kann zur Abfrageoptimierung analysiert werden.

Geschätzter Ausführungsplan

Anzeigen der tatsächlichen Ausführungspläne in ApexSQL Plan

Um den tatsächlichen Ausführungsplan einer Abfrage anzuzeigen, fahren Sie mit dem zuvor erwähnten zweiten Schritt fort. Klicken Sie nun, sobald der geschätzte Plan angezeigt wird, in der Hauptleiste von ApexSQL Plan auf die Schaltfläche „Ist“.

Klicken Sie in der Hauptleiste auf die Schaltfläche "Ist"

Sobald Sie auf die Schaltfläche „Ist“ klicken, wird der Ist-Ausführungsplan mit einer detaillierten Vorschau der Kostenparameter zusammen mit anderen Ausführungsplandaten angezeigt.

Tatsächlicher Ausführungsplan

Weitere Informationen zum Anzeigen von Ausführungsplänen finden Sie unter diesem Link .

Marcin Czyz
quelle
14

Mein Lieblingswerkzeug zum Abrufen und gründlichen Analysieren von Abfrageausführungsplänen ist SQL Sentry Plan Explorer . Es ist viel benutzerfreundlicher, bequemer und umfassender für die Detailanalyse und Visualisierung von Ausführungsplänen als SSMS.

Hier ist ein Beispiel-Screenshot, damit Sie eine Vorstellung davon bekommen, welche Funktionen das Tool bietet:

Screenshot des SQL Sentry Plan Explorer-Fensters

Dies ist nur eine der im Tool verfügbaren Ansichten. Beachten Sie eine Reihe von Registerkarten am unteren Rand des App-Fensters, mit denen Sie verschiedene Arten Ihrer Ausführungsplandarstellung und nützliche zusätzliche Informationen abrufen können.

Darüber hinaus habe ich keine Einschränkungen der kostenlosen Edition festgestellt, die die tägliche Verwendung verhindern oder Sie dazu zwingen, die Pro-Version zu erwerben. Wenn Sie sich also lieber an die kostenlose Edition halten, verbietet Ihnen nichts, dies zu tun.

UPDATE: (Dank an Martin Smith ) Plan Explorer ist jetzt kostenlos! Weitere Informationen finden Sie unter http://www.sqlsentry.com/products/plan-explorer/sql-server-query-view .

Alexander Abakumov
quelle
1
Wer sprach von Tools von Drittanbietern?
Basher
12
@basher: OP hat die Mittel mit MS-Tools oder irgendwie nicht eingeschränkt. Was lässt Sie denken, dass eine Antwort mit einem Tool eines Drittanbieters unangemessen ist?
Alexander Abakumov
3
Ich habe nur Spaß gemacht, wie Sie den Beginn Ihrer Antwort formuliert haben, Speaking of third-party toolsals niemand Tools von Drittanbietern erwähnte.
Basher
4
@Basher: Oh, schöner Fang! Vielen Dank! Ich habe meine Antwort umgeschrieben. Bitte zögern Sie nicht, ein Feedback zu geben und / oder es zu bewerten, wenn Sie möchten.
Alexander Abakumov
3
Übrigens gibt es jetzt nur noch eine Version sqlsentry.com/products/plan-explorer/sql-server-query-view
Martin Smith
7

Abfragepläne können über das query_post_execution_showplanEreignis aus einer Sitzung für erweiterte Ereignisse abgerufen werden . Hier ist eine XEvent-Beispielsitzung:

/*
    Generated via "Query Detail Tracking" template.
*/
CREATE EVENT SESSION [GetExecutionPlan] ON SERVER 
ADD EVENT sqlserver.query_post_execution_showplan(
    ACTION(package0.event_sequence,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)),

/* Remove any of the following events (or include additional events) as desired. */
ADD EVENT sqlserver.error_reported(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.module_end(SET collect_statement=(1)
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.rpc_completed(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.sp_statement_completed(SET collect_object_name=(1)
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.sql_batch_completed(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.sql_statement_completed(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.database_id,sqlserver.plan_handle,sqlserver.query_hash,sqlserver.query_plan_hash,sqlserver.session_id,sqlserver.sql_text,sqlserver.tsql_frame,sqlserver.tsql_stack)
    WHERE ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)) AND [package0].[equal_boolean]([sqlserver].[is_system],(0)))) 
ADD TARGET package0.ring_buffer
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)
GO

Nachdem Sie die Sitzung erstellt haben, gehen Sie (in SSMS) zum Objekt-Explorer und gehen Sie zu Management | Erweiterte Ereignisse | Sitzungen. Klicken Sie mit der rechten Maustaste auf die Sitzung "GetExecutionPlan" und starten Sie sie. Klicken Sie erneut mit der rechten Maustaste darauf und wählen Sie "Live-Daten ansehen".

Öffnen Sie als Nächstes ein neues Abfragefenster und führen Sie eine oder mehrere Abfragen aus. Hier ist eine für AdventureWorks:

USE AdventureWorks;
GO

SELECT p.Name AS ProductName, 
    NonDiscountSales = (OrderQty * UnitPrice),
    Discounts = ((OrderQty * UnitPrice) * UnitPriceDiscount)
FROM Production.Product AS p 
INNER JOIN Sales.SalesOrderDetail AS sod
    ON p.ProductID = sod.ProductID 
ORDER BY ProductName DESC;
GO

Nach ein oder zwei Augenblicken sollten auf der Registerkarte "GetExecutionPlan: Live Data" einige Ergebnisse angezeigt werden. Klicken Sie auf eines der Ereignisse query_post_execution_showplan im Raster und dann auf die Registerkarte "Abfrageplan" unter dem Raster. Es sollte ungefähr so ​​aussehen:

Geben Sie hier die Bildbeschreibung ein

EDIT : Der XEvent - Code und die Screenshot wurden von SQL / SSMS 2012 w / SP2 erzeugt. Wenn Sie SQL 2008 / R2 verwenden, können Sie das Skript möglicherweise optimieren, damit es ausgeführt wird. Da diese Version jedoch keine grafische Benutzeroberfläche hat, müssen Sie das Showplan-XML extrahieren, als * .sqlplan-Datei speichern und in SSMS öffnen. Das ist umständlich. XEvents war in SQL 2005 oder früher nicht vorhanden. Wenn Sie nicht mit SQL 2012 oder höher arbeiten, würde ich dringend eine der anderen hier veröffentlichten Antworten empfehlen.

Dave Mason
quelle
5

Ab SQL Server 2016+ wurde die Query Store-Funktion eingeführt, um die Leistung zu überwachen. Es bietet Einblick in die Auswahl und Leistung des Abfrageplans. Es ist kein vollständiger Ersatz für Trace- oder erweiterte Ereignisse, aber da es sich von Version zu Version weiterentwickelt, erhalten wir möglicherweise in zukünftigen Versionen von SQL Server einen voll funktionsfähigen Abfragespeicher. Der primäre Ablauf des Abfragespeichers

  1. Vorhandene SQL Server-Komponenten interagieren mit dem Abfragespeicher mithilfe des Query Store Managers.
  2. Der Query Store Manager legt fest, welcher Store verwendet werden soll, und übergibt die Ausführung an diesen Store (Plan- oder Laufzeitstatistik oder Query Wait Stats).
    • Plan Store - Behalten Sie die Ausführungsplaninformationen bei
    • Runtime Stats Store - Behalten Sie die Ausführungsstatistikinformationen bei
    • Abfragestatistikspeicher - Persistente Wartestatistikinformationen.
  3. Der Plan-, Laufzeitstatistik- und Wartespeicher verwendet den Abfragespeicher als Erweiterung für SQL Server.

Geben Sie hier die Bildbeschreibung ein

  1. Aktivieren des Abfragespeichers : Der Abfragespeicher funktioniert auf Datenbankebene auf dem Server.

    • Der Abfragespeicher ist für neue Datenbanken standardmäßig nicht aktiv.
    • Sie können den Abfragespeicher für den Master oder die tempdbDatenbank nicht aktivieren .
    • Verfügbar DMV

      sys.database_query_store_options (Transact-SQL)

  2. Sammeln von Informationen im Abfragespeicher : Wir erfassen alle verfügbaren Informationen aus den drei Speichern mithilfe von Query Store DMV (Data Management Views).

    • Abfrageplanspeicher : Behalten Sie die Ausführungsplaninformationen bei und es ist verantwortlich für die Erfassung aller Informationen, die sich auf die Abfragekompilierung beziehen.

      sys.query_store_query(Transact-SQL) sys.query_store_plan(Transact-SQL) sys.query_store_query_text(Transact-SQL)

    • Runtime Stats Store: Die Informationen zur Ausführungsstatistik bleiben erhalten und es handelt sich wahrscheinlich um den am häufigsten aktualisierten Speicher. Diese Statistiken repräsentieren Abfrageausführungsdaten.

      sys.query_store_runtime_stats (Transact-SQL)

    • Abfragestatistikspeicher speichern: Wartestatistikinformationen beibehalten und erfassen.

      sys.query_store_wait_stats (Transact-SQL)

ANMERKUNG: Der Abfragestatistikspeicher ist nur in SQL Server 2017+ verfügbar

vKillusion
quelle
4

Wie bei SQL Server Management Studio (bereits erläutert) ist es auch bei Datagrip möglich, wie hier erläutert .

  1. Klicken Sie mit der rechten Maustaste auf eine SQL-Anweisung und wählen Sie Plan erklären.
  2. Klicken Sie im Ausgabebereich auf Planen.
  3. Standardmäßig wird die Baumdarstellung der Abfrage angezeigt. Um den Abfrageplan anzuzeigen, klicken Sie auf das Symbol Visualisierung anzeigen oder drücken Sie Strg + Umschalt + Alt + U.
Daan
quelle
3

Hier ist eine wichtige Sache zu wissen, zusätzlich zu allem, was zuvor gesagt wurde.

Abfragepläne sind häufig zu komplex, um durch den integrierten XML- Spaltentyp dargestellt zu werden, der auf 127 Ebenen verschachtelter Elemente beschränkt ist. Dies ist einer der Gründe, warum sys.dm_exec_query_planNULL in früheren MS SQL-Versionen möglicherweise einen Fehler zurückgibt oder sogar auslöst. Daher ist es im Allgemeinen sicherer, stattdessen sys.dm_exec_text_query_plan zu verwenden. Letzteres bietet auch eine nützliche Bonusfunktion für die Auswahl eines Plans für eine bestimmte Abrechnung anstelle der gesamten Charge. So verwenden Sie es, um Pläne für aktuell ausgeführte Anweisungen anzuzeigen:

SELECT p.query_plan
FROM sys.dm_exec_requests AS r
OUTER APPLY sys.dm_exec_text_query_plan(
                r.plan_handle,
                r.statement_start_offset,
                r.statement_end_offset) AS p

Die Textspalte in der resultierenden Tabelle ist jedoch im Vergleich zu einer XML-Spalte nicht sehr praktisch. Um auf das Ergebnis zu klicken, das in einer separaten Registerkarte als Diagramm geöffnet werden soll, ohne den Inhalt in einer Datei speichern zu müssen, können Sie einen kleinen Trick verwenden (denken Sie daran, dass Sie nicht nur verwenden können CAST(... AS XML)), obwohl dies nur für a funktioniert einzelne Reihe:

SELECT Tag = 1, Parent = NULL, [ShowPlanXML!1!!XMLTEXT] = query_plan
FROM sys.dm_exec_text_query_plan(
                -- set these variables or copy values
                -- from the results of the above query
                @plan_handle,
                @statement_start_offset,
                @statement_end_offset)
FOR XML EXPLICIT
alkoln
quelle
2

Wie in diesem Artikel erläutert , gibt es zwei Ausführungsplantypen, die Sie bei Verwendung von SQL Server erhalten können.

Geschätzter Ausführungsplan

Der geschätzte Ausführungsplan wird vom Optimierer generiert, ohne die SQL-Abfrage auszuführen.

Um den geschätzten Ausführungsplan zu erhalten, müssen Sie den aktivieren SHOWPLAN_ALL Einstellung , bevor Sie die Abfrage ausführen.

SET SHOWPLAN_ALL ON

Wenn Sie nun die folgende SQL-Abfrage ausführen:

SELECT p.id
FROM post p
WHERE EXISTS (
  SELECT 1
  FROM post_comment pc
  WHERE
    pc.post_id = p.id AND
    pc.review = 'Bingo'
)
ORDER BY p.title
OFFSET 20 ROWS
FETCH NEXT 10 ROWS ONLY

SQL Server generiert den folgenden geschätzten Ausführungsplan:

| NodeId | Parent | LogicalOp            | EstimateRows | EstimateIO  | EstimateCPU | AvgRowSize | TotalSubtreeCost | EstimateExecutions |
|--------|--------|----------------------|--------------|-------------|-------------|------------|------------------|--------------------|
| 1      | 0      | NULL                 | 10           | NULL        | NULL        | NULL       | 0.03374284       | NULL               |
| 2      | 1      | Top                  | 10           | 0           | 3.00E-06    | 15         | 0.03374284       | 1                  |
| 4      | 2      | Distinct Sort        | 30           | 0.01126126  | 0.000504114 | 146        | 0.03373984       | 1                  |
| 5      | 4      | Inner Join           | 46.698       | 0           | 0.00017974  | 146        | 0.02197446       | 1                  |
| 6      | 5      | Clustered Index Scan | 43           | 0.004606482 | 0.0007543   | 31         | 0.005360782      | 1                  |
| 7      | 5      | Clustered Index Seek | 1            | 0.003125    | 0.0001581   | 146        | 0.0161733        | 43                 |

Nach dem Ausführen der Abfrage möchten wir den geschätzten Ausführungsplan abrufen. Sie müssen den deaktivieren, SHOWPLAN_ALLda andernfalls die aktuelle Datenbanksitzung nur den geschätzten Ausführungsplan generiert, anstatt die bereitgestellten SQL-Abfragen auszuführen.

SET SHOWPLAN_ALL OFF

Geschätzter Plan von SQL Server Management Studio

In der SQL Server Management Studio-Anwendung können Sie den geschätzten Ausführungsplan für jede SQL-Abfrage einfach abrufen, indem Sie auf die CTRL+LTastenkombination klicken.

Geben Sie hier die Bildbeschreibung ein

Tatsächlicher Ausführungsplan

Der eigentliche SQL-Ausführungsplan wird vom Optimierer beim Ausführen der SQL-Abfrage generiert. Wenn die Datenbanktabellenstatistiken korrekt sind, sollte der tatsächliche Plan nicht wesentlich vom geschätzten Plan abweichen.

Um den tatsächlichen Ausführungsplan für SQL Server abzurufen, müssen Sie die STATISTICS IO, TIME, PROFILEEinstellungen aktivieren , wie im folgenden SQL-Befehl dargestellt:

SET STATISTICS IO, TIME, PROFILE ON

Wenn Sie nun die vorherige Abfrage ausführen, generiert SQL Server den folgenden Ausführungsplan:

| Rows | Executes | NodeId | Parent | LogicalOp            | EstimateRows | EstimateIO  | EstimateCPU | AvgRowSize | TotalSubtreeCost |
|------|----------|--------|--------|----------------------|--------------|-------------|-------------|------------|------------------|
| 10   | 1        | 1      | 0      | NULL                 | 10           | NULL        | NULL        | NULL       | 0.03338978       |
| 10   | 1        | 2      | 1      | Top                  | 1.00E+01     | 0           | 3.00E-06    | 15         | 0.03338978       |
| 30   | 1        | 4      | 2      | Distinct Sort        | 30           | 0.01126126  | 0.000478783 | 146        | 0.03338679       |
| 41   | 1        | 5      | 4      | Inner Join           | 44.362       | 0           | 0.00017138  | 146        | 0.02164674       |
| 41   | 1        | 6      | 5      | Clustered Index Scan | 41           | 0.004606482 | 0.0007521   | 31         | 0.005358581      |
| 41   | 41       | 7      | 5      | Clustered Index Seek | 1            | 0.003125    | 0.0001581   | 146        | 0.0158571        |

SQL Server parse and compile time:
   CPU time = 8 ms, elapsed time = 8 ms.

(10 row(s) affected)
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'post'. Scan count 0, logical reads 116, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'post_comment'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(6 row(s) affected)

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 1 ms.

Nachdem Sie die Abfrage ausgeführt haben, möchten wir den tatsächlichen Ausführungsplan erhalten. Sie müssen die STATISTICS IO, TIME, PROFILE ONEinstellungen wie folgt deaktivieren :

SET STATISTICS IO, TIME, PROFILE OFF

Aktueller Plan für SQL Server Management Studio

In der SQL Server Management Studio-Anwendung können Sie den geschätzten Ausführungsplan für jede SQL-Abfrage einfach abrufen, indem Sie auf die CTRL+MTastenkombination klicken.

Geben Sie hier die Bildbeschreibung ein

Weitere Informationen zum Abrufen eines Ausführungsplans bei Verwendung von SQL Server finden Sie in diesem Artikel .

Vlad Mihalcea
quelle
2

Sie können dies auch über Powershell mit SET STATISTICS XML ON tun, um den tatsächlichen Plan abzurufen. Ich habe es so geschrieben, dass es Pläne mit mehreren Anweisungen zu einem Plan zusammenführt.

    ########## BEGIN : SCRIPT VARIABLES #####################
    [string]$server = '.\MySQLServer'
    [string]$database = 'MyDatabase'
    [string]$sqlCommand = 'EXEC sp_ExampleSproc'
    [string]$XMLOutputFileName = 'sp_ExampleSproc'
    [string]$XMLOutputPath = 'C:\SQLDumps\ActualPlans\'
    ########## END   : SCRIPT VARIABLES #####################

    #Set up connection
    $connectionString = "Persist Security Info=False;Integrated Security=true;Connection Timeout=0;Initial Catalog=$database;Server=$server"
    $connection = new-object system.data.SqlClient.SQLConnection($connectionString)

    #Set up commands
    $command = new-object system.data.sqlclient.sqlcommand($sqlCommand,$connection)
    $command.CommandTimeout = 0
    $commandXMLActPlanOn = new-object system.data.sqlclient.sqlcommand("SET STATISTICS XML ON",$connection)
    $commandXMLActPlanOff = new-object system.data.sqlclient.sqlcommand("SET STATISTICS XML OFF",$connection)

    $connection.Open()

    #Enable session XML plan
    $result = $commandXMLActPlanOn.ExecuteNonQuery()

    #Execute SP and return resultsets into a dataset
    $adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
    $dataset = New-Object System.Data.DataSet
    $adapter.Fill($dataSet) | Out-Null

    #Set up output file name and path
    [string]$fileNameDateStamp = get-date -f yyyyMMdd_HHmmss
    [string]$XMLOutputFilePath = "$XMLOutputPath$XMLOutputFileName`_$fileNameDateStamp.sqlplan"

    #Pull XML plans out of dataset and merge into one multi-statement plan
    [int]$cntr = 1
    ForEach($table in $dataset.Tables)
    {
            if($table.Columns[0].ColumnName -eq "Microsoft SQL Server 2005 XML Showplan")
            {

                [string]$fullXMLPlan = $Table.rows[0]."Microsoft SQL Server 2005 XML Showplan"

                if($cntr -eq 1)
                    {

                    [regex]$rx = "\<ShowPlanXML xmlns\=.{1,}\<Statements\>"
                    [string]$startXMLPlan = $rx.Match($fullXMLPlan).Value
                    [regex]$rx = "\<\/Statements\>.{1,}\<\/ShowPlanXML\>"
                    [string]$endXMLPlan = $rx.Match($fullXMLPlan).Value

                    $startXMLPlan | out-file -Append -FilePath $XMLOutputFilePath

                    }

                [regex]$rx = "\<StmtSimple.{1,}\<\/StmtSimple\>"
                [string]$bodyXMLPlan = $rx.Match($fullXMLPlan).Value

                $bodyXMLPlan | out-file -Append -FilePath $XMLOutputFilePath

                $cntr += 1
            } 
    }

    $endXMLPlan | out-file -Append -FilePath $XMLOutputFilePath

    #Disable session XML plan
    $result = $commandXMLActPlanOff.ExecuteNonQuery()

    $connection.Close()
Guy Bishop
quelle
0

Das Erklären des Ausführungsplans kann sehr detailliert sein und nimmt eine beträchtliche Lesezeit in Anspruch. Wenn Sie jedoch vor der Abfrage 'EXPLAIN' verwenden, sollten Sie viele Informationen erhalten, einschließlich der Teile, die zuerst ausgeführt wurden, und so weiter. Wenn Sie ein bisschen mehr Details dazu lesen möchten, habe ich einen kleinen Blog darüber zusammengestellt, der Sie auch auf die richtigen Refs hinweist. https://medium.com/swlh/jetbrains-datagrip-explain-plan-ac406772c470

Abd Rmdn
quelle