# 機能設計書 7-sp_BlitzAnalysis

## 概要

本ドキュメントは、SQL Server First Responder Kitのsp_BlitzAnalysisストアドプロシージャの機能設計について記載する。sp_BlitzAnalysisは、sp_BlitzFirst、sp_BlitzCache、sp_BlitzWhoの出力データを時系列で集計・分析し、パフォーマンス傾向を可視化する診断ツールである。

### 本機能の処理概要

sp_BlitzAnalysisは、他のBlitzツール群が出力したログデータを統合的に分析し、指定期間のパフォーマンス傾向を把握するためのストアドプロシージャである。

**業務上の目的・背景**：sp_BlitzFirst、sp_BlitzCache、sp_BlitzWhoを定期実行してログを蓄積している環境において、蓄積されたデータから特定期間のパフォーマンス傾向を分析したい場合に利用する。個別のツール出力を手動で確認するよりも、統合的な視点で問題を特定できる。

**機能の利用シーン**：
- 定期ジョブで蓄積したBlitzFirstデータの傾向分析
- 特定期間のパフォーマンス問題の原因調査
- 待機統計、ファイルI/O、パフォーマンスカウンターの時系列分析
- 問題クエリの特定と傾向把握

**主要な処理内容**：
1. 入力パラメータの検証とデフォルト値設定
2. BlitzFirstデータの集計と出力
3. 待機統計データの集計と出力
4. ファイル統計データの集計と出力
5. パフォーマンスカウンターデータの集計と出力
6. BlitzCacheデータの集計と出力
7. BlitzWhoデータの集計と出力

**関連システム・外部連携**：
- sp_BlitzFirstの出力テーブル群
- sp_BlitzCacheの出力テーブル
- sp_BlitzWhoの出力テーブル

**権限による制御**：
- 分析対象テーブルへのSELECT権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 14 | sp_BlitzAnalysis結果画面 | 主機能 | sp_BlitzFirst、sp_BlitzCache、sp_BlitzWhoのログを分析・集計表示 |

## 機能種別

データ分析 / パフォーマンス傾向分析 / レポーティング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| @Help | TINYINT | No | ヘルプ表示 | デフォルト0 |
| @StartDate | DATETIMEOFFSET(7) | No | 検索開始日時 | NULL時は1時間前 |
| @EndDate | DATETIMEOFFSET(7) | No | 検索終了日時 | NULL時は1時間後または現在 |
| @OutputDatabaseName | NVARCHAR(256) | No | 出力先データベース名 | デフォルト'DBAtools' |
| @OutputSchemaName | NVARCHAR(256) | No | 出力先スキーマ名 | デフォルト'dbo' |
| @OutputTableNameBlitzFirst | NVARCHAR(256) | No | BlitzFirstテーブル名 | デフォルト'BlitzFirst' |
| @OutputTableNameFileStats | NVARCHAR(256) | No | FileStatsテーブル名 | デフォルト'BlitzFirst_FileStats' |
| @OutputTableNamePerfmonStats | NVARCHAR(256) | No | PerfmonStatsテーブル名 | デフォルト'BlitzFirst_PerfmonStats' |
| @OutputTableNameWaitStats | NVARCHAR(256) | No | WaitStatsテーブル名 | デフォルト'BlitzFirst_WaitStats' |
| @OutputTableNameBlitzCache | NVARCHAR(256) | No | BlitzCacheテーブル名 | デフォルト'BlitzCache' |
| @OutputTableNameBlitzWho | NVARCHAR(256) | No | BlitzWhoテーブル名 | デフォルト'BlitzWho' |
| @Servername | NVARCHAR(128) | No | 対象サーバー名 | デフォルト@@SERVERNAME |
| @Databasename | NVARCHAR(128) | No | フィルタ対象データベース | NULL許可 |
| @BlitzCacheSortorder | NVARCHAR(20) | No | BlitzCacheソート順 | デフォルト'cpu' |
| @MaxBlitzFirstPriority | INT | No | 含めるBlitzFirst最大プライオリティ | デフォルト249 |
| @ReadLatencyThreshold | INT | No | 読み取りレイテンシ閾値(ms) | デフォルト100 |
| @WriteLatencyThreshold | INT | No | 書き込みレイテンシ閾値(ms) | デフォルト100 |
| @WaitStatsTop | TINYINT | No | 待機統計の上位件数 | デフォルト10 |
| @Version | VARCHAR(30) | No | バージョン（OUTPUT） | 出力専用 |
| @VersionDate | DATETIME | No | バージョン日付（OUTPUT） | 出力専用 |
| @VersionCheckMode | BIT | No | バージョンチェックモード | デフォルト0 |
| @BringThePain | BIT | No | 4時間以上の分析許可 | デフォルト0 |
| @Maxdop | INT | No | 並列度 | デフォルト1 |
| @Debug | BIT | No | デバッグモード | デフォルト0 |

### 入力データソース

- BlitzFirstテーブル（@OutputTableNameBlitzFirst）
- BlitzFirst_FileStats_Deltasテーブル（@OutputTableNameFileStats + '_Deltas'）
- BlitzFirst_PerfmonStats_Actualsテーブル（@OutputTableNamePerfmonStats + '_Actuals'）
- BlitzFirst_WaitStats_Deltasテーブル（@OutputTableNameWaitStats + '_Deltas'）
- BlitzCacheテーブル（@OutputTableNameBlitzCache）
- BlitzWho_Deltasテーブル（@OutputTableNameBlitzWho + '_Deltas'）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ServerToReportOn | NVARCHAR(128) | 対象サーバー名 |
| PrioritesToInclude | NVARCHAR | プライオリティ範囲 |
| StartDatetime | DATETIMEOFFSET(7) | 開始日時 |
| EndDatetime | DATETIMEOFFSET(7) | 終了日時 |

**BlitzFirstサマリー出力**:
| 項目名 | 型 | 説明 |
|--------|-----|------|
| Priority | TINYINT | プライオリティ |
| FindingsGroup | VARCHAR(50) | 発見グループ |
| Finding | VARCHAR(200) | 発見内容 |
| TotalOccurrences | INT | 発生回数 |
| FirstOccurrence | DATETIMEOFFSET(7) | 初回発生日時 |
| LastOccurrence | DATETIMEOFFSET(7) | 最終発生日時 |

**待機統計出力**:
| 項目名 | 型 | 説明 |
|--------|-----|------|
| ServerName | NVARCHAR(128) | サーバー名 |
| CheckDate | DATETIMEOFFSET | チェック日時 |
| wait_type | NVARCHAR | 待機タイプ |
| WaitsRank | INT | 待機ランク |
| wait_time_ms_delta | BIGINT | 待機時間差分(ms) |
| wait_time_ms_per_wait | DECIMAL | 待機あたり時間 |

**ファイル統計出力**:
| 項目名 | 型 | 説明 |
|--------|-----|------|
| CheckDate | DATETIMEOFFSET | チェック日時 |
| io_stall_ms_breached | VARCHAR(3) | 閾値超過フラグ |
| PhysicalPath | NVARCHAR | ファイルパス |
| max_io_stall_read_ms_average | DECIMAL | 平均読み取りストール |
| max_io_stall_write_ms_average | DECIMAL | 平均書き込みストール |

### 出力先

- 画面表示（複数の結果セット）

## 処理フロー

### 処理シーケンス

```
1. パラメータ検証と初期化
   ├─ @OutputDatabaseName存在確認
   ├─ @BlitzCacheSortorder検証
   ├─ @Maxdop検証
   └─ @StartDate/@EndDate設定

2. レポート情報出力
   └─ サーバー名、期間情報の表示

3. BlitzFirstデータ分析
   ├─ #BlitzFirstCountsに集計
   └─ 発見グループ別サマリー出力

4. 待機統計データ分析
   └─ 時系列での上位待機出力

5. ファイル統計データ分析
   └─ 閾値超過チェック付きで出力

6. パフォーマンスカウンター分析
   └─ 時系列でのカウンター出力

7. BlitzCacheデータ分析
   └─ ソート順別クエリ分析
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{@Help = 1?}
    B -->|Yes| C[ヘルプ出力]
    C --> Z[終了]
    B -->|No| D[パラメータ検証]
    D --> E{DB存在確認}
    E -->|No| F[エラー終了]
    E -->|Yes| G{@BlitzCacheSortorder有効?}
    G -->|No| F
    G -->|Yes| H{4時間超 & all & !@BringThePain?}
    H -->|Yes| F
    H -->|No| I[レポート情報出力]
    I --> J[BlitzFirst分析]
    J --> K[待機統計分析]
    K --> L[ファイル統計分析]
    L --> M[Perfmon分析]
    M --> N[BlitzCache分析]
    N --> O[BlitzWho分析]
    O --> Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | デフォルト期間 | @StartDate未指定時は1時間前から | @StartDate=NULL |
| BR-002 | 期間制限 | 4時間超でall指定時は@BringThePain=1が必要 | @BlitzCacheSortorder='all' |
| BR-003 | 有効ソート順 | cpu, reads, writes, duration, executions, memory grant, spills, all | 常時 |
| BR-004 | Maxdop上限 | CPU数を超える場合は0に設定 | @Maxdop > cpu_count |
| BR-005 | テーブル存在確認 | テーブル不在時はスキップ | 常時 |

### 計算ロジック

**待機あたり時間計算**:
```sql
ISNULL((CAST([wait_time_ms_delta] AS DECIMAL(38,2))
  /NULLIF(CAST([waiting_tasks_count_delta] AS DECIMAL(38,2)),0)),0) AS [wait_time_ms_per_wait]
```

**I/Oストール閾値判定**:
```sql
CASE
  WHEN MAX([io_stall_read_ms_average]) > @ReadLatencyThreshold THEN 'Yes'
  WHEN MAX([io_stall_write_ms_average]) > @WriteLatencyThreshold THEN 'Yes'
  ELSE 'No'
END AS [io_stall_ms_breached]
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 参照 | BlitzFirst | SELECT | 発見事項の集計 |
| 参照 | BlitzFirst_FileStats_Deltas | SELECT | ファイルI/O統計の取得 |
| 参照 | BlitzFirst_PerfmonStats_Actuals | SELECT | パフォーマンスカウンターの取得 |
| 参照 | BlitzFirst_WaitStats_Deltas | SELECT | 待機統計の取得 |
| 参照 | BlitzCache | SELECT | クエリプランキャッシュ情報の取得 |
| 参照 | BlitzWho_Deltas | SELECT | セッション情報の取得 |

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

#### #BlitzFirstCounts（一時テーブル）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | Priority, FindingsGroup, Finding | BlitzFirstからの集計 | 発見事項カウント |
| INSERT | TotalOccurrences | COUNT(*) | 発生回数 |
| INSERT | FirstOccurrence | MIN(CheckDate) | 初回発生 |
| INSERT | LastOccurrence | MAX(CheckDate) | 最終発生 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | DB不在 | @OutputDatabaseNameが存在しない | RAISERRORでエラー通知、RETURN |
| - | ソート順エラー | @BlitzCacheSortorderが無効な値 | RAISERRORでエラー通知、RETURN |
| - | 期間制限エラー | 4時間超でall指定かつ@BringThePain=0 | RAISERRORでエラー通知、RETURN |

### リトライ仕様

特定のリトライ機能は実装されていない。

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

明示的なトランザクション制御は行われない。各クエリはOPTION (RECOMPILE, MAXDOP)で実行される。

## パフォーマンス要件

- @Maxdopパラメータで並列度を制御可能
- 4時間超のデータ分析は@BringThePain=1で明示的に許可が必要
- 各クエリはRECOMPILEオプションで実行

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

- 分析対象テーブルへのSELECT権限が必要
- 動的SQLを使用するため、入力値はQUOTENAME()で保護

## 備考

- バージョン: 8.29（2026年2月3日時点）
- sys.dm_exec_query_statsのmemory grant/spillsカラム存在を動的にチェック
- テーブルが存在しない場合はスキップして処理を継続

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sp_BlitzAnalysis.sql | `sp_BlitzAnalysis.sql` | **108-115行目**: #BlitzFirstCounts一時テーブル定義 |

**読解のコツ**: #BlitzFirstCountsはBlitzFirst発見事項を集計するための一時テーブル。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | sp_BlitzAnalysis.sql | `sp_BlitzAnalysis.sql` | **10-35行目**: ALTER PROCEDURE定義とパラメータ |
| 2-2 | sp_BlitzAnalysis.sql | `sp_BlitzAnalysis.sql` | **37-38行目**: SET NOCOUNTとSTATISTICS XML OFF |
| 2-3 | sp_BlitzAnalysis.sql | `sp_BlitzAnalysis.sql` | **40行目**: バージョン情報設定 |

**主要処理フロー**:
1. **42-45行目**: @VersionCheckModeによる早期リターン
2. **47-74行目**: @Help=1時のヘルプ出力
3. **88-93行目**: @OutputDatabaseName存在確認

#### Step 3: パラメータ検証を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | sp_BlitzAnalysis.sql | `sp_BlitzAnalysis.sql` | **117-129行目**: @BlitzCacheSortorder検証 |
| 3-2 | sp_BlitzAnalysis.sql | `sp_BlitzAnalysis.sql` | **131-141行目**: @Maxdop検証 |
| 3-3 | sp_BlitzAnalysis.sql | `sp_BlitzAnalysis.sql` | **157-184行目**: @StartDate/@EndDate設定 |
| 3-4 | sp_BlitzAnalysis.sql | `sp_BlitzAnalysis.sql` | **192-197行目**: @BringThePain確認 |

#### Step 4: データ分析処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | sp_BlitzAnalysis.sql | `sp_BlitzAnalysis.sql` | **207-292行目**: BlitzFirst分析 |
| 4-2 | sp_BlitzAnalysis.sql | `sp_BlitzAnalysis.sql` | **294-365行目**: 待機統計分析 |
| 4-3 | sp_BlitzAnalysis.sql | `sp_BlitzAnalysis.sql` | **367-442行目**: ファイル統計分析 |
| 4-4 | sp_BlitzAnalysis.sql | `sp_BlitzAnalysis.sql` | **444-490行目**: Perfmon分析 |
| 4-5 | sp_BlitzAnalysis.sql | `sp_BlitzAnalysis.sql` | **492-600行目**: BlitzCache分析（CTE構築） |

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

```
sp_BlitzAnalysis
    │
    ├─ パラメータ検証
    │   ├─ DB_ID() でDB存在確認
    │   ├─ sys.dm_os_sys_info でCPU数取得
    │   └─ sys.all_columns でmemory grant/spills確認
    │
    ├─ #BlitzFirstCounts一時テーブル
    │
    ├─ sp_executesql
    │   ├─ BlitzFirst分析クエリ
    │   ├─ 待機統計分析クエリ
    │   ├─ ファイル統計分析クエリ
    │   ├─ Perfmon分析クエリ
    │   └─ BlitzCache分析クエリ
    │
    └─ OBJECT_ID() でテーブル存在確認
```

### データフロー図

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

パラメータ ──────────────────▶ パラメータ検証 ─────────────────▶ レポート情報
   │                              │
   │                              ▼
BlitzFirstテーブル ──────────▶ 集計クエリ ──────────────────────▶ 発見サマリー
   │                              │                                   │
   │                              ▼                                   │
WaitStats_Deltasテーブル ────▶ 時系列分析 ─────────────────────▶ 待機統計
   │                              │                                   │
   │                              ▼                                   │
FileStats_Deltasテーブル ────▶ 閾値判定 ───────────────────────▶ ファイルI/O
   │                              │                                   │
   │                              ▼                                   │
PerfmonStats_Actualsテーブル ▶ 時系列出力 ─────────────────────▶ Perfmonカウンター
   │                              │                                   │
   │                              ▼                                   │
BlitzCacheテーブル ──────────▶ ソート別集計 ───────────────────▶ クエリ分析
   │                              │
   ▼                              ▼
BlitzWho_Deltasテーブル ─────▶ 時系列出力 ─────────────────────▶ セッション情報
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| sp_BlitzAnalysis.sql | `sp_BlitzAnalysis.sql` | ソース | メインストアドプロシージャ定義 |
| sp_BlitzFirst.sql | `sp_BlitzFirst.sql` | 関連 | 分析対象データの生成元 |
| sp_BlitzCache.sql | `sp_BlitzCache.sql` | 関連 | 分析対象データの生成元 |
| sp_BlitzWho.sql | `sp_BlitzWho.sql` | 関連 | 分析対象データの生成元 |
