# 機能設計書 414-Get-DbaWaitStatistic

## 概要

本ドキュメントは、SQL Serverの待機統計を取得してパフォーマンス分析とトラブルシューティングに活用する`Get-DbaWaitStatistic`機能の設計を定義する。

### 本機能の処理概要

本機能は、sys.dm_os_wait_statsからSQL Serverの待機統計を分析し、パフォーマンスボトルネックやリソース競合問題を特定する。Paul Randal氏の手法に基づき、待機タイプの分類、タイミングメトリクスと割合の計算、診断説明の提供を行う。

**業務上の目的・背景**：SQL Serverがディスク I/O、メモリ圧迫、ロック問題、その他のリソース制約のいずれを待機しているかを特定することで、クエリパフォーマンスを低下させている原因を見つけることができる。待機統計はSQL Serverのパフォーマンストラブルシューティングの基礎であり、「どこが痛いか教えてください」アプローチの中核をなす。

**機能の利用シーン**：
- SQL Serverパフォーマンス問題の初期診断
- ボトルネック（I/O、CPU、メモリ、ロック）の特定
- パフォーマンスベースラインの取得
- 定期的なヘルスチェック

**主要な処理内容**：
1. 指定されたSQL Serverインスタンスへの接続（最小バージョン2005）
2. sys.dm_os_wait_statsから待機統計を取得
3. 閾値によるフィルタリングと累積パーセンテージ計算
4. 待機タイプの分類とカテゴリ割り当て
5. Paul Randal氏の診断ノートの付加

**関連システム・外部連携**：SQL Server DMV (sys.dm_os_wait_stats)

**権限による制御**：VIEW SERVER STATE権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | コマンドライン | 主画面 | PowerShellコンソールからの実行 |

## 機能種別

データ取得・分析処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstance[] | Yes | 対象SQL Serverインスタンス（2005以降） | パイプライン入力可能 |
| SqlCredential | PSCredential | No | 代替認証資格情報 | Windows/SQL認証対応 |
| Threshold | int | No | 累積パーセンテージ閾値（デフォルト: 95） | 1-100 |
| IncludeIgnorable | switch | No | 無視可能な待機タイプを含める | - |
| EnableException | switch | No | 例外の詳細表示有効化 | - |

### 入力データソース

SQL Server DMV: sys.dm_os_wait_stats

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverホストのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| WaitType | string | 待機タイプ名（例: PAGEIOLATCH_EX, LCK_M_IX） |
| Category | string | 待機カテゴリ（Buffer IO, Lock, Network IO, CPU等） |
| WaitSeconds | decimal | 合計待機時間（秒） |
| ResourceSeconds | decimal | リソース待機時間（秒） |
| SignalSeconds | decimal | シグナル待機時間（秒） |
| WaitCount | bigint | 待機発生回数 |
| Percentage | decimal | 全待機時間に対する割合（0-100） |
| AverageWaitSeconds | decimal | 平均待機時間（秒） |
| AverageResourceSeconds | decimal | 平均リソース待機時間（秒） |
| AverageSignalSeconds | decimal | 平均シグナル待機時間（秒） |
| Ignorable | bool | 無視可能な待機タイプかどうか |
| URL | XML/string | sqlskills.com詳細ドキュメントへのリンク |
| Notes | string | 診断説明（Select-Object *で表示） |

### 出力先

PowerShellパイプライン(PSCustomObject)

## 処理フロー

### 処理シーケンス

```
1. beginブロック: 設定データの準備
   └─ 1.1 $details: 主要待機タイプの詳細説明（Paul Randal氏のノート）
   └─ 1.2 $category: 待機タイプからカテゴリへのマッピング
   └─ 1.3 $ignorable: 無視可能な待機タイプリスト
   └─ 1.4 SQLクエリの構築（IncludeIgnorableに応じて分岐）

2. processブロック: インスタンスごとの処理ループ
   └─ 2.1 Connect-DbaInstance（MinimumVersion 9）で接続
   └─ 2.2 SQLクエリ実行
   └─ 2.3 各行をPSCustomObjectに変換
   └─ 2.4 カテゴリ、Notes、URL等の付加
   └─ 2.5 Select-DefaultViewで出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[詳細説明/カテゴリ/無視リスト定義]
    B --> C{IncludeIgnorable?}
    C -->|Yes| D[全待機タイプ取得SQL]
    C -->|No| E[無視リスト除外SQL]
    D --> F[Write-Message Debug]
    E --> F
    F --> G{各SqlInstanceをループ}
    G --> H[Connect-DbaInstance MinVer=9]
    H --> I{接続成功?}
    I -->|No| J[Stop-Function/Continue]
    J --> G
    I -->|Yes| K[クエリ実行]
    K --> L{各行をループ}
    L --> M{IncludeIgnorable?}
    M -->|No| N{Ignorable待機?}
    N -->|Yes| O[continue]
    N -->|No| P[PSCustomObject作成]
    M -->|Yes| P
    P --> Q[Category/Notes/URL付加]
    Q --> R[Select-DefaultView出力]
    R --> L
    L -->|完了| G
    G -->|完了| S[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 最小バージョン | SQL Server 2005（バージョン9）以上が必要 | Connect-DbaInstance時 |
| BR-002 | デフォルト閾値 | Thresholdのデフォルト値は95% | パラメータ未指定時 |
| BR-003 | 無視リストフィルタ | IncludeIgnorable未指定時は無視可能待機をフィルタアウト | デフォルト |
| BR-004 | 待機回数フィルタ | waiting_tasks_count > 0のみ取得 | 常時 |

### 計算ロジック

```sql
-- 累積パーセンテージ計算
CASE WHEN SUM([wait_time_ms]) OVER() = 0 THEN NULL
ELSE 100.0 * [wait_time_ms] / SUM([wait_time_ms]) OVER() END AS [Percentage]

-- 閾値フィルタリング
HAVING SUM([W2].[Percentage]) - MAX([W1].[Percentage]) < $Threshold
```

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 待機統計取得 | sys.dm_os_wait_stats | SELECT | DMVから待機統計を取得 |

### テーブル別操作詳細

#### sys.dm_os_wait_stats (DMV)

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | wait_type | - | 待機タイプ名 |
| SELECT | wait_time_ms | - | 合計待機時間（ミリ秒） |
| SELECT | signal_wait_time_ms | - | シグナル待機時間（ミリ秒） |
| SELECT | waiting_tasks_count | > 0 | 待機タスク数 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | Connect-DbaInstance失敗 | Stop-FunctionでContinue |
| VersionError | バージョンエラー | SQL Server 2005未満 | MinimumVersionで接続拒否 |

### リトライ仕様

リトライ処理なし（単一試行）

## トランザクション仕様

読み取り専用クエリのためトランザクション管理不要

## パフォーマンス要件

- DMVクエリのため通常は高速（数秒以内）
- 待機タイプ数と閾値に応じた結果行数

## セキュリティ考慮事項

- VIEW SERVER STATE権限が必要
- SQL認証/Windows認証/Azure AD認証に対応
- 資格情報はPSCredentialで安全に渡される

## 備考

- Paul Randal氏の参照記事: https://www.sqlskills.com/blogs/paul/wait-statistics-or-please-tell-me-where-it-hurts/
- Brent Ozar氏とMarcin Gminski氏のカテゴリマッピングを参考
- 約800種類以上の待機タイプをカテゴリ分類

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaWaitStatistic.ps1 | `public/Get-DbaWaitStatistic.ps1` | $details変数の構造（124-160行目）- 待機タイプ説明 |
| 1-2 | Get-DbaWaitStatistic.ps1 | `public/Get-DbaWaitStatistic.ps1` | $category変数の構造（165-809行目）- カテゴリマッピング |
| 1-3 | Get-DbaWaitStatistic.ps1 | `public/Get-DbaWaitStatistic.ps1` | $ignorable変数（811-845行目）- 無視可能待機リスト |

**読解のコツ**: $detailsは主要待機タイプの診断ノート、$categoryは全待機タイプのカテゴリ分類、$ignorableはフィルタ対象リスト

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaWaitStatistic.ps1 | `public/Get-DbaWaitStatistic.ps1` | パラメータ定義（113-120行目） |

**主要処理フロー**:
1. **113-120行目**: パラメータ定義（SqlInstance, Threshold, IncludeIgnorable）
2. **117行目**: Thresholdデフォルト値95

#### Step 3: SQLクエリ構築を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaWaitStatistic.ps1 | `public/Get-DbaWaitStatistic.ps1` | IncludeIgnorable時のSQL（848-874行目） |
| 3-2 | Get-DbaWaitStatistic.ps1 | `public/Get-DbaWaitStatistic.ps1` | 通常時のSQL（876-905行目） |

**主要処理フロー**:
- **848-874行目**: IncludeIgnorable時 - 全待機タイプを取得
- **876行目**: $IgnorableListを構築
- **877-905行目**: 通常時 - 無視リストを除外してクエリ

#### Step 4: 結果処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Get-DbaWaitStatistic.ps1 | `public/Get-DbaWaitStatistic.ps1` | 結果ループ処理（923-947行目） |

**主要処理フロー**:
- **923行目**: foreach ($row in $server.Query($sql))
- **924-927行目**: IncludeIgnorable未指定時の追加フィルタ
- **929-946行目**: PSCustomObject作成（Category, Notes, URL付加）

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

```
Get-DbaWaitStatistic
    │
    ├─ beginブロック
    │      ├─ $details定義（診断ノート）
    │      ├─ $category定義（カテゴリマッピング）
    │      ├─ $ignorable定義（無視リスト）
    │      └─ SQLクエリ構築
    │
    ├─ Connect-DbaInstance (MinimumVersion 9)
    │      └─ SMO接続の確立
    │
    ├─ $server.Query()
    │      └─ sys.dm_os_wait_statsクエリ実行
    │
    └─ Select-DefaultView
           └─ 出力プロパティの選択（Notes除外）
```

### データフロー図

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

SqlInstance ──────▶ Connect-DbaInstance ──────┐
                   (MinimumVersion=9)         │
                                              │
SqlCredential ────▶ 認証処理 ────────────────┘
                          │
Threshold ────────▶ SQLクエリ構築 ◀──── IncludeIgnorable
                          │
                          ▼
              sys.dm_os_wait_stats
                          │
                          ▼
               foreach ($row in results)
                          │
                   ┌──────┴──────┐
                   ▼             ▼
              $category    $details
              (カテゴリ)   (Notes)
                   │             │
                   └──────┬──────┘
                          ▼
                   PSCustomObject
                          │
                          ▼
               Select-DefaultView
                          │
                          ▼
                   パイプライン出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaWaitStatistic.ps1 | `public/Get-DbaWaitStatistic.ps1` | ソース | メイン関数実装 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続処理 |
