# 画面設計書 215-実行プラン

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける「実行プラン」機能（Get-DbaExecutionPlan、Export-DbaExecutionPlan）の画面設計書です。SQL Serverのプランキャッシュから実行プランを取得・エクスポートし、パフォーマンス分析を支援する機能を提供します。

### 本画面の処理概要

**業務上の目的・背景**：SQL Server管理者やDBAは、クエリパフォーマンスの問題をトラブルシューティングするために実行プランを分析する必要があります。プランキャッシュに保存された実行プランを取得・分析することで、リアルタイムでクエリをキャプチャすることなく、実際に実行されているクエリとその実行方法を確認できます。.sqlplanファイルとしてエクスポートすることで、SQL Server Management Studioで詳細な分析が可能になります。

**画面へのアクセス方法**：PowerShellコンソールから `Get-DbaExecutionPlan` または `Export-DbaExecutionPlan` コマンドを実行します。

**主要な操作・処理内容**：
1. **Get-DbaExecutionPlan**:
   - sys.dm_exec_query_stats、sys.dm_exec_query_plan、sys.dm_exec_text_query_planを使用してプランキャッシュからプランを取得
   - データベース、作成日時、最終実行日時でフィルタリング
   - XML実行プランを解析してメタデータを抽出
2. **Export-DbaExecutionPlan**:
   - プランキャッシュから実行プランを取得
   - .sqlplan形式でファイルにエクスポート
   - Get-DbaExecutionPlanの出力をパイプライン入力として受け入れ

**画面遷移**：CLIコマンドのため画面遷移はありません。Get-DbaExecutionPlanの出力はExport-DbaExecutionPlanにパイプできます。

**権限による表示制御**：SQL Serverへの接続にはVIEW SERVER STATE権限が必要です（DMVへのアクセス）。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 243 | Get-DbaExecutionPlan | 主機能 | 実行プランの取得 |
| 217 | Export-DbaExecutionPlan | 主機能 | 実行プランのエクスポート |

## 画面種別

コマンドライン（CLI）実行画面

## URL/ルーティング

```powershell
# 実行プラン取得
Get-DbaExecutionPlan -SqlInstance <インスタンス名> [-Database <データベース名>] [-SinceCreation <日時>]

# 実行プランエクスポート
Export-DbaExecutionPlan -SqlInstance <インスタンス名> -Path <出力先パス>

# パイプライン利用
Get-DbaExecutionPlan -SqlInstance <インスタンス名> | Export-DbaExecutionPlan -Path <出力先パス>
```

## 入出力項目

### Get-DbaExecutionPlan パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|------|-------------|------|
| SqlInstance | DbaInstanceParameter[] | Yes | - | ターゲットSQL Serverインスタンス |
| SqlCredential | PSCredential | No | - | 代替認証情報 |
| Database | object[] | No | - | 対象データベース |
| ExcludeDatabase | object[] | No | - | 除外するデータベース |
| SinceCreation | datetime | No | - | 指定日時以降に作成されたプランをフィルタ |
| SinceLastExecution | datetime | No | - | 指定日時以降に実行されたプランをフィルタ |
| ExcludeEmptyQueryPlan | switch | No | $false | 空のクエリプランを除外 |
| Force | switch | No | $false | 全カラムを返す（DMVの生データ） |
| EnableException | switch | No | $false | 例外を有効化 |

### Export-DbaExecutionPlan パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|------|-------------|------|
| SqlInstance | DbaInstanceParameter[] | Yes（NotPipedセット） | - | ターゲットSQL Serverインスタンス |
| SqlCredential | PSCredential | No | - | 代替認証情報 |
| Database | object[] | No | - | 対象データベース |
| ExcludeDatabase | object[] | No | - | 除外するデータベース |
| Path | string | No | Path.DbatoolsExport | .sqlplanファイルの出力先ディレクトリ |
| SinceCreation | datetime | No | - | 指定日時以降に作成されたプランをフィルタ |
| SinceLastExecution | datetime | No | - | 指定日時以降に実行されたプランをフィルタ |
| InputObject | object[] | Yes（Pipedセット） | - | Get-DbaExecutionPlanからの入力 |
| EnableException | switch | No | $false | 例外を有効化 |

## 表示項目

### Get-DbaExecutionPlan 出力

| プロパティ名 | 型 | 説明 |
|-------------|-----|------|
| ComputerName | string | SQL Serverホストコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| DatabaseName | string | データベース名 |
| ObjectName | string | オブジェクト名（プロシージャ等） |
| QueryPosition | int | バッチ内のステートメント位置 |
| SqlHandle | string | SQLハンドル（16進数） |
| PlanHandle | string | プランハンドル（16進数） |
| CreationTime | datetime | プラン作成日時 |
| LastExecutionTime | datetime | 最終実行日時 |
| StatementType | string | ステートメントタイプ（SELECT/INSERT等） |
| StatementSubTreeCost | decimal | サブツリーコスト |
| StatementEstRows | decimal | 推定行数 |
| QueryHash | string | クエリハッシュ |
| QueryPlanHash | string | プランハッシュ |
| QueryPlan | XML | 実行プランXML |
| BatchQueryPlanRaw | XML | バッチプランXML（非表示） |
| SingleStatementPlanRaw | XML | 単一ステートメントプランXML（非表示） |
| PlanWarnings | object | プラン警告 |

### Export-DbaExecutionPlan 出力

| プロパティ名 | 型 | 説明 |
|-------------|-----|------|
| ComputerName | string | SQL Serverホストコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| DatabaseName | string | データベース名 |
| SqlHandle | string | SQLハンドル（16進数） |
| CreationTime | datetime | プラン作成日時 |
| LastExecutionTime | datetime | 最終実行日時 |
| OutputFile | string | 出力先ファイルパス |

## イベント仕様

### 1-Get-DbaExecutionPlan実行時

1. Connect-DbaInstanceでSQL Serverに接続（最低バージョン9 = SQL Server 2005）
2. Forceパラメータに基づいてSELECT文を構築
3. WHERE条件を構築（Database、SinceCreation、SinceLastExecution、ExcludeDatabase、ExcludeEmptyQueryPlan）
4. DMVクエリを実行
5. Forceの場合: 生のDataTableを返す
6. 通常の場合: XML実行プランを解析してPSCustomObjectを生成
7. SqlHandleとPlanHandleを16進数文字列に変換

### 2-Export-DbaExecutionPlan実行時

1. Pathがディレクトリかどうかを確認
2. InputObjectがある場合: パイプライン入力を処理
3. SqlInstanceが指定された場合: プランキャッシュをクエリ
4. 各プランについて:
   - ファイル名を生成（{インスタンス名}-{データベース名}-{位置}-{SqlHandle}）
   - BatchQueryPlanRawを{ファイル名}-batch.sqlplanに保存
   - SingleStatementPlanRawを{ファイル名}.sqlplanに保存
5. OutputFileプロパティを追加して出力

## データベース更新仕様

このコマンドはデータベースを更新しません。プランキャッシュからの読み取りのみを行います。

## メッセージ仕様

| 種別 | メッセージ | 発生条件 |
|------|----------|---------|
| エラー | Failure | 接続エラー時 |
| エラー | Query Failure Failure | クエリ実行エラー時 |
| エラー | Path ({Path}) must be a directory | Pathがディレクトリでない場合 |
| エラー | Skipped query plan for {fileName} because it is null | プランがnullの場合 |
| エラー | Issue collecting execution plans | プラン収集エラー時 |
| Verbose | Adding creation time | SinceCreation指定時 |
| Verbose | Adding last execution time | SinceLastExecution指定時 |
| Debug | SQL Statement: {sql} | 実行されるSQL文 |

## 例外処理

| 例外条件 | 動作 |
|---------|------|
| 接続エラー | Stop-Functionでエラーを報告し、次のインスタンスに継続 |
| SQL Server 2005未満 | Connect-DbaInstanceでMinimumVersionチェックにより拒否 |
| Pathがディレクトリでない | Stop-Functionで処理を中断 |
| プランがnull | Stop-Functionでエラーを報告し、次のプランに継続 |
| クエリ実行エラー | Stop-Functionでエラーを報告し、次のインスタンスに継続 |

## 備考

- SQL Server 2005以降でサポート（バージョン9以上）
- sys.dm_exec_query_stats、sys.dm_exec_query_plan、sys.dm_exec_text_query_planを使用
- エクスポートされる.sqlplanファイルはSSMSで直接開ける
- Forceパラメータで全DMVカラムを取得可能（詳細分析向け）
- 大規模なプランキャッシュの場合、多数のファイルが生成される可能性あり

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaExecutionPlan.ps1 | `public/Get-DbaExecutionPlan.ps1` | 出力オブジェクトの構造（行236-270） |
| 1-2 | Export-DbaExecutionPlan.ps1 | `public/Export-DbaExecutionPlan.ps1` | エクスポート出力の構造（行276-290, 182-183） |

**読解のコツ**: Get-DbaExecutionPlanの出力には多数のXML関連プロパティがあり、Select-DefaultViewで一部が非表示になっています（行270）。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaExecutionPlan.ps1 | `public/Get-DbaExecutionPlan.ps1` | パラメータ定義（行146-157）とDMVクエリ構築（行169-224） |
| 2-2 | Export-DbaExecutionPlan.ps1 | `public/Export-DbaExecutionPlan.ps1` | パラメータセット（NotPiped/Piped）とExport-Plan内部関数（行146-185） |

**主要処理フロー (Get-DbaExecutionPlan)**:
1. **行164**: Connect-DbaInstanceでMinimumVersion 9（SQL 2005以上）をチェック
2. **行169-180**: ForceによってSELECT文を切り替え
3. **行182-187**: FROMクエリでDMVをCROSS APPLY
4. **行189-222**: WHERE条件の動的構築
5. **行227-272**: ForceなしではXMLを解析してPSCustomObjectを生成

**主要処理フロー (Export-DbaExecutionPlan)**:
1. **行190-197**: Pathがディレクトリかどうかを検証
2. **行146-185**: Export-Plan内部関数でファイル保存処理
3. **行157-167**: BatchQueryPlanRawを{ファイル名}-batch.sqlplanに保存
4. **行169-179**: SingleStatementPlanRawを{ファイル名}.sqlplanに保存

### プログラム呼び出し階層図

```
Get-DbaExecutionPlan
    |
    +-- Connect-DbaInstance (MinimumVersion 9)
    |      +-- SQL Server接続確立
    |
    +-- server.Query($sql)
    |      +-- DMVからプランキャッシュ取得
    |
    +-- XML解析
    |      +-- SingleStatementPlan解析
    |      +-- BatchQueryPlan解析
    |
    +-- PSCustomObject生成
           +-- プロパティ設定
           +-- Select-DefaultView適用

Export-DbaExecutionPlan
    |
    +-- Get-DbaExecutionPlan（直接またはパイプライン）
    |
    +-- Export-Plan（内部関数）
    |      +-- ファイル名生成
    |      +-- BatchQueryPlanRaw.Save()
    |      +-- SingleStatementPlanRaw.Save()
    |
    +-- OutputFile追加
           +-- Select-DefaultView適用
```

### データフロー図

```
[入力]                    [処理]                              [出力]

SqlInstance ───────▶ Connect-DbaInstance ───────▶ Server SMO Object
      |
      v
                    DMVクエリ実行 ───────────────▶ DataTable
      |
      v
                    XMLパース ───────────────────▶ 解析済みプラン情報
      |
      v
                    PSCustomObject生成 ─────────▶ 実行プラン出力
      |
      v
                    Export-Plan（ファイル保存）──▶ .sqlplanファイル
                           |
                           +── {instance}-{db}-{pos}-{handle}-batch.sqlplan
                           +── {instance}-{db}-{pos}-{handle}.sqlplan
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaExecutionPlan.ps1 | `public/Get-DbaExecutionPlan.ps1` | ソース | プラン取得コマンド |
| Export-DbaExecutionPlan.ps1 | `public/Export-DbaExecutionPlan.ps1` | ソース | プランエクスポートコマンド |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |

### DMVクエリ構造

```sql
SELECT DB_NAME(deqp.dbid) AS DatabaseName,
       OBJECT_NAME(deqp.objectid) AS ObjectName,
       detqp.query_plan AS SingleStatementPlan,
       deqp.query_plan AS BatchQueryPlan,
       ROW_NUMBER() OVER (ORDER BY Statement_Start_offset) AS QueryPosition,
       sql_handle AS SqlHandle,
       plan_handle AS PlanHandle,
       creation_time AS CreationTime,
       last_execution_time AS LastExecutionTime
FROM sys.dm_exec_query_stats deqs
CROSS APPLY sys.dm_exec_text_query_plan(deqs.plan_handle,
    deqs.statement_start_offset,
    deqs.statement_end_offset) AS detqp
CROSS APPLY sys.dm_exec_query_plan(deqs.plan_handle) AS deqp
CROSS APPLY sys.dm_exec_sql_text(deqs.plan_handle) AS execText
WHERE [条件]
```
