Microsoft SQL Serverで、クエリ/ストアドプロシージャのクエリ実行プランを取得するにはどうすればよいですか?
Microsoft SQL Serverで、クエリ/ストアドプロシージャのクエリ実行プランを取得するにはどうすればよいですか?
回答:
実行プランを取得する方法はいくつかありますが、使用する方法は状況によって異なります。通常、SQL Server Management Studioを使用して計画を取得できますが、何らかの理由でSQL Server Management Studioでクエリを実行できない場合は、SQL Server Profilerまたは検査によって計画を取得できると便利です。計画キャッシュ。
SQL Serverには、実行計画を非常に簡単に取得できる2つの優れた機能が備わっています。[クエリ]メニューにある[実際の実行計画を含める]メニュー項目がチェックされていることを確認し、通常どおりにクエリを実行します。 。
ストアドプロシージャのステートメントの実行プランを取得しようとしている場合は、次のようにストアドプロシージャを実行する必要があります。
exec p_Example 42
クエリが完了すると、結果ペインに「実行計画」というタイトルの追加のタブが表示されます。多くのステートメントを実行した場合、このタブに多くのプランが表示されることがあります。
ここから、SQL Server Management Studioで実行プランを検査するか、プランを右クリックして[名前を付けて実行プランを保存...]を選択して、プランをXML形式のファイルに保存できます。
この方法は方法1と非常によく似ています(実際、これはSQL Server Management Studioが内部で行うことです)。
クエリを実行する前に、次のいずれかのステートメントを実行します。ステートメントはバッチ内の唯一のステートメントでなければなりません。つまり、同時に別のステートメントを実行することはできません。
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
これらは接続オプションであるため、接続ごとに1回だけ実行する必要があります。この時点から、実行されるすべてのステートメントには、目的の形式の実行プランを含む追加の結果セットが付随します。通常、プランを表示するのと同じようにクエリを実行するだけです。
完了したら、次のステートメントでこのオプションをオフにできます。
SET <<option>> OFF
あなたが強い好みがない限り、私の推奨はSTATISTICS XML
オプションを使用することです。このオプションは、SQL Server Management Studioの[実際の実行計画を含める]オプションと同等であり、最も便利な形式でほとんどの情報を提供します。
SHOWPLAN_TEXT
-クエリを実行せずに、基本的なテキストベースの推定実行プランを表示しますSHOWPLAN_ALL
-クエリを実行せずに、テキストベースの推定見積もりとコスト見積もりを表示しますSHOWPLAN_XML
-クエリを実行せずに、XMLベースの推定見積もりとコスト見積もりを表示します。これは、SQL Server Management Studioの[推定実行プランの表示...]オプションに相当します。STATISTICS PROFILE
-クエリを実行し、テキストベースの実際の実行プランを表示します。STATISTICS XML
-クエリを実行し、XMLベースの実際の実行プランを表示します。これは、SQL Server Management Studioの[実際の実行プランを含める]オプションに相当します。クエリを直接実行できない場合(またはクエリを直接実行しても速度が低下しない場合-クエリの実行計画が適切でないことを思い出してください)、SQL Serverプロファイラートレースを使用して計画をキャプチャできます。アイデアは、 "Showplan"イベントの1つをキャプチャしているトレースの実行中にクエリを実行することです。
負荷によっては、本番環境でこの方法を使用できますが、注意が必要なことは明らかです。SQL Serverのプロファイリングのメカニズムは、データベースへの影響を最小限に抑えるように設計されているが、これはそこにないことを意味するものではありません任意のパフォーマンスへの影響。データベースが頻繁に使用されている場合、トレースで正しいプランをフィルタリングおよび特定する際に問題が発生する場合もあります。DBAが貴重なデータベースでこれを行って満足しているかどうかは、DBAに明らかに確認する必要があります。
取得するプランは、SQL Server Management Studioの[実際の実行プランを含める]オプションと同等です。
クエリを直接実行できず、プロファイラートレースもキャプチャできない場合でも、SQLクエリプランのキャッシュを調べることにより、推定プランを取得できます。
SQL Server DMVにクエリを実行して、プランキャッシュを検査します。以下は、すべてのキャッシュされたクエリプランを(xmlとして)SQLテキストとともに一覧表示する基本的なクエリです。ほとんどのデータベースでは、関心のある計画だけに結果を絞り込むために、追加のフィルター句を追加する必要があります。
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)
このクエリを実行し、プランXMLをクリックしてプランを新しいウィンドウで開きます。右クリックして[名前を付けて実行プランを保存...]を選択し、プランをXML形式でファイルに保存します。
非常に多くの要因が関与しているため(テーブルやインデックススキーマから、格納されているデータやテーブルの統計に至るまで)、関心のあるデータベース(通常、パフォーマンスが発生しているもの)から実行プランを取得するように常に心がける必要があります。問題)。
暗号化されたストアドプロシージャの実行プランはキャプチャできません。
実際の実行計画は、一方でSQL Serverが実際に、クエリを実行1であると推定実行計画SQL Serverは、それがどのようなうまくいくでしょうクエリを実行せずに行います。論理的には同等ですが、実際の実行プランには、クエリの実行時に実際に何が起こったかに関する詳細と統計が含まれているため、はるかに便利です。これは、SQL Serverの見積もりがオフになっている問題(統計が古くなっている場合など)を診断する場合に不可欠です。
これは、それだけで(無料の)本として十分価値のあるトピックです。
SET STATISTICS XML ON
クエリの最初と、計画の出力に表示したくないSET STATISTICS XML OFF|ON
周辺領域を入力してください:クエリに不要な反復(WHILE)が含まれている場合に、これが便利です。実行プランで確認します(そうしないと、SQL SERVERで表示するには重すぎて長くなります。
すでに投稿されている包括的な回答に加えて、実行計画にプログラムからアクセスして情報を抽出できると便利な場合があります。これのサンプルコードは以下です。
DECLARE @TraceID INT
EXEC StartCapture @@SPID, @TraceID OUTPUT
EXEC sp_help 'sys.objects' /*<-- Call your stored proc of interest here.*/
EXEC StopCapture @TraceID
StartCapture
定義の例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
StopCapture
定義の例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
前の回答で説明した方法のほかに、無料の実行プランビューアとクエリ最適化ツールApexSQLプランを使用することもできます(最近。
ApexSQLプランをインストールしてSQL Server Management Studioに統合できるため、実行プランをSSMSから直接表示できます。
ApexSQLプランでの推定実行プランの表示
ApexSQLプランでの実際の実行プランの表示
クエリの実際の実行プランを表示するには、前述の2番目のステップから続行しますが、今度は推定プランが表示されたら、ApexSQLプランのメインリボンバーから[実際]ボタンをクリックします。
「実際」ボタンをクリックすると、実際の実行プランが表示され、他の実行プランデータとともにコストパラメータの詳細なプレビューが表示されます。
実行プランの表示の詳細については、このリンクをクリックしてください。
クエリ実行プランを取得して詳細に分析するための私のお気に入りのツールは、SQL Sentry Plan Explorerです。です。これは、SSMSよりも実行計画の詳細分析と視覚化に関して、はるかにユーザーフレンドリーで便利で包括的なものです。
ツールが提供する機能を理解するためのスクリーンショットの例を以下に示します。
ツールで使用できるビューの1つにすぎません。アプリウィンドウの下部にある一連のタブに注目してください。これを使用すると、さまざまなタイプの実行プランの表現と役立つ追加情報を取得できます。
さらに、私はその無料版が日常的にそれを使用することを妨げる、またはあなたが最終的にプロ版を購入することを強いる制限に気づいていません。したがって、無料版を使い続けることを希望する場合は、そうすることを禁じるものはありません。
更新:(Martin Smithに感謝)Plan Explorerが無料になりました!詳細については、http://www.sqlsentry.com/products/plan-explorer/sql-server-query-viewを参照してください。
Speaking of third-party tools
サードパーティのツールについて誰も言及しなかったとき、あなたが答えの始まりをどのように言ったかで冗談を言っていました。
クエリプランは、query_post_execution_showplan
イベントを介して拡張イベントセッションから取得できます。次にXEventセッションの例を示します。
/*
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
セッションを作成したら、(SSMSで)オブジェクトエクスプローラーに移動し、[管理]、[詳細]の順に進みます。拡張イベント| セッション。「GetExecutionPlan」セッションを右クリックして開始します。もう一度右クリックして、[ライブデータを見る]を選択します。
次に、新しいクエリウィンドウを開き、1つ以上のクエリを実行します。以下は、AdventureWorksの1つです。
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
しばらくすると、[GetExecutionPlan:ライブデータ]タブに結果が表示されます。グリッドでいずれかのquery_post_execution_showplanイベントをクリックし、グリッドの下にある[クエリプラン]タブをクリックします。これは次のようになります。
編集:XEventコードとスクリーンショットは、SQL / SSMS 2012 w / SP2から生成されました。SQL 2008 / R2を使用している場合は、スクリプトを微調整して実行することができる場合があります。ただし、そのバージョンにはGUIがないため、プラン表示XMLを抽出し、*。sqlplanファイルとして保存して、SSMSで開く必要があります。それは面倒です。XEventsはSQL 2005以前には存在しませんでした。したがって、SQL 2012以降を使用していない場合は、ここに掲載されている他の回答の1つを強くお勧めします。
SQL Server 2016以降、パフォーマンスを監視するためのクエリストア機能が導入されました。クエリプランの選択とパフォーマンスに関する洞察を提供します。これは、トレースイベントや拡張イベントの完全な置き換えではありませんが、バージョンごとに進化しているため、SQL Serverの将来のリリースでは、完全に機能するクエリストアを取得する可能性があります。クエリストアの主要なフロー
クエリストアの有効化:クエリストアは、サーバーのデータベースレベルで機能します。
tempdb
データベースのクエリストアを有効にすることはできません。
sys.database_query_store_options
(Transact-SQL)
クエリストアでの情報の収集:クエリストアDMV(データ管理ビュー)を使用して、3つのストアからすべての利用可能な情報を収集します。
クエリプランストア: 実行プラン情報を保持し、クエリのコンパイルに関連するすべての情報を取得する責任があります。
sys.query_store_query
(Transact-SQL)sys.query_store_plan
(Transact-SQL)sys.query_store_query_text
(Transact-SQL)
ランタイム統計ストア: 実行統計情報を保持しており、おそらく最も頻繁に更新されるストアです。これらの統計はクエリ実行データを表します。
sys.query_store_runtime_stats
(Transact-SQL)
クエリ待機統計ストア: 待機統計情報の永続化とキャプチャ。
sys.query_store_wait_stats
(Transact-SQL)
注:クエリ待機統計ストアは、SQL Server 2017以降でのみ使用できます
これまでに述べたことすべてに加えて、知っておくべき重要なことが1つあります。
多くの場合、クエリプランは複雑すぎて、ネストされた要素のレベルが127に制限されている組み込みのXML列タイプで表すことができません。これが、以前のMS SQLバージョンでsys.dm_exec_query_planがNULL
エラーを返す、またはエラーをスローする理由の1つであるため、通常は代わりにsys.dm_exec_text_query_planを使用する方が安全です。後者には、バッチ全体ではなく特定のステートメントのプランを選択するという便利なボーナス機能もあります。これを使用して、現在実行中のステートメントのプランを表示する方法は次のとおりです。
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
ただし、結果のテーブルのテキスト列は、XML列と比較するとあまり便利ではありません。結果をクリックしてダイアグラムとして別のタブで開くことができるようにするには、その内容をファイルに保存する必要はありませんが、ちょっとしたトリックを使用できます(を使用できないことに注意してくださいCAST(... AS XML)
)。これは、単一行:
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
この記事で説明したように、SQL Serverを使用すると、2種類の実行プランを取得できます。
推定実行プランは、SQLクエリを実行せずにオプティマイザーによって生成されます。
推定実行プランを取得するには、 SHOWPLAN_ALL
するには、クエリを実行する前に設定ます。
SHOWPLAN_ALLをオンに設定
ここで、次のSQLクエリを実行すると、
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は、次の推定実行プランを生成します。
| 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 |
推定実行プランの取得に関心のあるクエリを実行した後、SHOWPLAN_ALL
as を無効にする必要があります。無効にしないと、現在のデータベースセッションは、提供されたSQLクエリを実行するのではなく、推定実行プランのみを生成します。
SET SHOWPLAN_ALL OFF
SQL Server Management Studioアプリケーションでは、CTRL+L
キーショートカットを押すことで、SQLクエリの推定実行プランを簡単に取得できます。
実際のSQL実行プランは、SQLクエリの実行時にオプティマイザーによって生成されます。データベーステーブルの統計が正確である場合、実際の計画は推定されたものと大幅に異なるべきではありません。
SQL Serverで実際の実行プランを取得するにはSTATISTICS IO, TIME, PROFILE
、次のSQLコマンドで示されているように、設定を有効にする必要があります。
SET STATISTICS IO, TIME, PROFILE ON
ここで、前のクエリを実行すると、SQL Serverは次の実行プランを生成します。
| 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.
実際の実行プランを取得することに関心のあるクエリを実行した後、次のSTATISTICS IO, TIME, PROFILE ON
ような設定を無効にする必要があります。
SET STATISTICS IO, TIME, PROFILE OFF
SQL Server Management Studioアプリケーションでは、CTRL+M
キーショートカットを押すことで、SQLクエリの推定実行プランを簡単に取得できます。
SQL Serverを使用する場合の実行プランの取得について詳しくは、こちらの記事をご覧ください。
また、SET STATISTICS XML ONを使用してpowershellから実行し、実際の計画を取得することもできます。複数ステートメントのプランを1つのプランにマージするように記述しました。
########## 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()
実行プランの説明は非常に詳細であり、かなりの読み取り時間を要しますが、要約すると、クエリの前に「説明」を使用すると、最初に実行された部分などの多くの情報が得られます。これについてもう少し詳しく知りたい場合は、これについての小さなブログをまとめました。これにより、正しい参照先も示されます。 https://medium.com/swlh/jetbrains-datagrip-explain-plan-ac406772c470