# 帳票設計書 3-sp_BlitzIndex

## 概要

本ドキュメントは、SQL Server First Responder Kitのsp_BlitzIndexストアドプロシージャが出力するインデックス分析帳票の設計を記述する。

### 本帳票の処理概要

sp_BlitzIndexは、データベースのインデックス設計とパフォーマンスを分析し、改善提案を出力するストアドプロシージャである。インデックスの使用状況、重複インデックス、不足インデックス、フィルファクター設定、統計情報の状態など、インデックスに関する包括的な診断を行い、最適化のための具体的な提案を提供する。

**業務上の目的・背景**：インデックスはSQL Serverのパフォーマンスに直接影響する重要な要素である。不適切なインデックス設計は、クエリの遅延、ストレージの無駄遣い、更新処理のオーバーヘッドを引き起こす。本帳票は、DBAがインデックスの健全性を定期的に評価し、パフォーマンス問題を予防することを目的としている。

**帳票の利用シーン**：
- データベース設計レビュー
- パフォーマンスチューニング作業
- ストレージ容量の最適化
- インデックス再構築計画の策定
- 新規インデックス追加の検討

**主要な出力内容**：
1. インデックス定義と使用状況サマリー
2. 重複インデックスの検出と削除推奨
3. 不足インデックスの提案（クエリオプティマイザ推奨）
4. 使用されていないインデックスの特定
5. インデックスの断片化状態
6. 統計情報の更新状況
7. カラムストアインデックスの詳細情報

**帳票の出力タイミング**：
- ストアドプロシージャ `EXEC sp_BlitzIndex` の手動実行時
- SQL Server Agentジョブによる定期実行時
- パフォーマンス監査時

**帳票の利用者**：
- データベース管理者（DBA）
- データベース設計者
- パフォーマンスエンジニア
- アプリケーションアーキテクト

## 帳票種別

インデックス分析レポート / 診断一覧表

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | SQL Server Management Studio | N/A | `EXEC sp_BlitzIndex` 実行 |
| N/A | Azure Data Studio | N/A | `EXEC sp_BlitzIndex` 実行 |
| N/A | コマンドライン | sqlcmd | スクリプト実行 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | TABLE / NONE |
| 用紙サイズ | N/A（結果セットとして出力） |
| 向き | N/A |
| ファイル名 | N/A（テーブル出力時は@OutputTableName指定） |
| 出力方法 | 結果セット返却 / テーブル書き込み |
| 文字コード | NVARCHAR（Unicode） |

### モード別出力

| Mode | 説明 |
|------|------|
| 0 | 診断モード（デフォルト） - 問題検出と改善提案 |
| 1 | サマリーモード - インデックス使用状況のサマリー |
| 2 | インデックス使用詳細 - 全インデックスの使用統計 |
| 3 | 不足インデックス詳細 - クエリオプティマイザ推奨 |
| 4 | 詳細診断 - より詳細な診断情報 |

## 帳票レイアウト

### レイアウト概要（Mode=0）

```
┌─────────────────────────────────────────────────────────────────────┐
│  結果セット: インデックス診断結果                                    │
├─────────────────────────────────────────────────────────────────────┤
│  Priority | findings_group | finding | database_name | details | ...│
│  -------- | -------------- | ------- | ------------- | ------- | ...│
│     1     | Index Issues   | ...     | UserDB        | ...     | ...│
│    50     | Performance    | ...     | UserDB        | ...     | ...│
│   ...     | ...            | ...     | ...           | ...     | ...│
└─────────────────────────────────────────────────────────────────────┘
```

### 出力カラム詳細（診断モード）

| No | 項目名 | 説明 | データ型 | 表示形式 |
|----|-------|------|----------|---------|
| 1 | Priority | 問題の優先度 | INT | 数値 |
| 2 | findings_group | 検出カテゴリ | NVARCHAR(4000) | テキスト |
| 3 | finding | 検出内容 | NVARCHAR(200) | テキスト |
| 4 | database_name | データベース名 | NVARCHAR(128) | テキスト |
| 5 | URL | 詳細情報URL | NVARCHAR(200) | ハイパーリンク |
| 6 | details | 詳細説明 | NVARCHAR(MAX) | テキスト |
| 7 | index_definition | インデックス定義 | NVARCHAR(MAX) | テキスト |
| 8 | secret_columns | 隠しカラム情報 | NVARCHAR(MAX) | テキスト |
| 9 | index_usage_summary | 使用状況サマリー | NVARCHAR(MAX) | テキスト |
| 10 | index_size_summary | サイズサマリー | NVARCHAR(MAX) | テキスト |
| 11 | create_tsql | インデックス作成SQL | NVARCHAR(MAX) | SQL |
| 12 | more_info | 追加情報クエリ | NVARCHAR(MAX) | SQL |

### 出力カラム詳細（#IndexSanity一時テーブル）

| No | 項目名 | 説明 | データ型 |
|----|-------|------|----------|
| 1 | database_id | データベースID | SMALLINT |
| 2 | object_id | オブジェクトID | INT |
| 3 | index_id | インデックスID | INT |
| 4 | index_type | インデックス種類 | TINYINT |
| 5 | schema_name | スキーマ名 | NVARCHAR(128) |
| 6 | object_name | テーブル名 | NVARCHAR(128) |
| 7 | index_name | インデックス名 | NVARCHAR(128) |
| 8 | key_column_names | キーカラム | NVARCHAR(MAX) |
| 9 | include_column_names | INCLUDEカラム | NVARCHAR(MAX) |
| 10 | filter_definition | フィルター定義 | NVARCHAR(MAX) |
| 11 | is_unique | ユニークフラグ | BIT |
| 12 | is_primary_key | 主キーフラグ | BIT |
| 13 | user_seeks | シーク回数 | BIGINT |
| 14 | user_scans | スキャン回数 | BIGINT |
| 15 | user_lookups | ルックアップ回数 | BIGINT |
| 16 | user_updates | 更新回数 | BIGINT |

## 出力条件

### 入力パラメータ

| パラメータ名 | データ型 | デフォルト値 | 説明 |
|-------------|----------|-------------|------|
| @ObjectName | NVARCHAR(386) | NULL | 'dbname.schema.table'形式 |
| @DatabaseName | NVARCHAR(128) | NULL | 対象データベース |
| @SchemaName | NVARCHAR(128) | NULL | 対象スキーマ |
| @TableName | NVARCHAR(261) | NULL | 対象テーブル |
| @Mode | TINYINT | 0 | 出力モード（0-4） |
| @Filter | TINYINT | 0 | フィルター（0=なし, 1=低使用除外, 2=500MB以上のみ） |
| @SkipPartitions | BIT | 0 | パーティション情報をスキップ |
| @SkipStatistics | BIT | 1 | 統計情報をスキップ |
| @GetAllDatabases | BIT | 0 | 全データベース対象 |
| @ShowColumnstoreOnly | BIT | 0 | カラムストアのみ表示 |
| @BringThePain | BIT | 0 | 詳細分析有効化 |
| @IgnoreDatabases | NVARCHAR(MAX) | NULL | 除外データベース（カンマ区切り） |
| @ThresholdMB | INT | 250 | 最小オブジェクトサイズ（MB） |
| @OutputType | VARCHAR(20) | 'TABLE' | 出力形式 |
| @IncludeInactiveIndexes | BIT | 0 | 未使用インデックスを含む |
| @ShowAllMissingIndexRequests | BIT | 0 | 全不足インデックス表示 |
| @SortOrder | NVARCHAR(50) | NULL | ソート順（Mode=2のみ） |
| @SortDirection | NVARCHAR(4) | 'DESC' | ソート方向（Mode=2のみ） |

### ソート順（Mode=2）

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | @SortOrderで指定 | @SortDirectionで指定 |

### 改ページ条件

結果セットのため改ページなし。

## データベース参照仕様

### 参照テーブル/DMV一覧

| テーブル/DMV名 | 用途 | 結合条件 |
|---------------|------|---------|
| sys.indexes | インデックス定義取得 | object_id, index_id |
| sys.index_columns | インデックスカラム情報 | object_id, index_id |
| sys.columns | カラム定義 | object_id, column_id |
| sys.dm_db_index_usage_stats | インデックス使用統計 | database_id, object_id, index_id |
| sys.dm_db_index_operational_stats | 操作統計 | database_id, object_id, index_id |
| sys.dm_db_missing_index_details | 不足インデックス詳細 | - |
| sys.dm_db_missing_index_groups | 不足インデックスグループ | - |
| sys.dm_db_missing_index_group_stats | 不足インデックス統計 | - |
| sys.dm_db_partition_stats | パーティション統計 | - |
| sys.stats | 統計情報 | object_id, stats_id |
| sys.dm_db_stats_properties | 統計プロパティ | - |

### テーブル別参照項目詳細

#### sys.indexes

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| name | index_name | - | インデックス名 |
| type | index_type | - | 0=ヒープ, 1=クラスタ化等 |
| is_unique | is_unique | - | ユニーク制約 |
| is_primary_key | is_primary_key | - | 主キー |
| fill_factor | fill_factor | - | フィルファクター |
| is_disabled | is_disabled | - | 無効化状態 |

#### sys.dm_db_index_usage_stats

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| user_seeks | user_seeks | - | シーク操作回数 |
| user_scans | user_scans | - | スキャン操作回数 |
| user_lookups | user_lookups | - | ルックアップ回数 |
| user_updates | user_updates | - | 更新操作回数 |
| last_user_seek | last_user_seek | - | 最終シーク日時 |
| last_user_scan | last_user_scan | - | 最終スキャン日時 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| total_reads | user_seeks + user_scans + user_lookups | - | 総読み取り回数 |
| reads_per_write | total_reads / user_updates | 小数点以下2桁 | 読み取り/書き込み比 |
| index_size_summary | 各パーティションサイズの合計 | MB単位 | - |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[sp_BlitzIndex実行] --> B{@Help = 1?}
    B -->|Yes| C[ヘルプ表示して終了]
    B -->|No| D{@GetAllDatabases?}
    D -->|Yes| E[全DBループ処理]
    D -->|No| F[対象DB特定]
    E --> G[一時テーブル作成]
    F --> G
    G --> H[#IndexSanity作成]
    H --> I[インデックス情報収集]
    I --> J[使用統計取得]
    J --> K{@Mode判定}
    K -->|0| L[診断チェック実行]
    K -->|1| M[サマリー生成]
    K -->|2| N[使用詳細出力]
    K -->|3| O[不足インデックス出力]
    K -->|4| P[詳細診断出力]
    L --> Q[結果出力]
    M --> Q
    N --> Q
    O --> Q
    P --> Q
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 無効なOutputType | 'TABLE'/'NONE'以外 | Invalid value for parameter @OutputType | TABLE または NONE を指定 |
| 無効な統計サンプリング率 | 0以下または100超 | Invalid value for parameter @UsualStatisticsSamplingPercent | 1-100を指定 |
| 出力パラメータ不足 | NONE時に出力先未指定 | @OutputTableName等の指定が必要 | 必須パラメータを指定 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 環境により変動（テーブル数×インデックス数） |
| 目標出力時間 | データベースサイズ依存 |
| 同時出力数上限 | 制限なし |

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

- VIEW DATABASE STATE権限が必要
- @GetAllDatabases使用時は全DBへのアクセス権限が必要
- スキーマ/テーブル名は機密情報の可能性あり
- 出力テーブルへのアクセス制御が必要

## 備考

- バージョン: 8.29（2026年2月3日リリース）
- ライセンス: MIT License
- 公式サイト: http://FirstResponderKit.org
- Azure SQL Database対応
- インメモリOLTPインデックス対応

---

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

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

### 推奨読解順序

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

まず、出力結果を格納する一時テーブルの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sp_BlitzIndex.sql | `sp_BlitzIndex.sql` | 行366-384: #BlitzIndexResults定義 |
| 1-2 | sp_BlitzIndex.sql | `sp_BlitzIndex.sql` | 行386-500: #IndexSanity定義（主要データテーブル） |

**読解のコツ**: #IndexSanityテーブルには計算カラム（AS句）が多数あり、index_definition等の複雑な文字列生成ロジックを確認すること。

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

処理の起点となるストアドプロシージャのシグネチャとパラメータを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | sp_BlitzIndex.sql | `sp_BlitzIndex.sql` | 行15-47: ALTER PROCEDUREとパラメータ定義 |

**主要処理フロー**:
1. **行53**: バージョン情報の設定
2. **行61-111**: @Help=1の場合のヘルプ出力
3. **行139-162**: @ObjectName のパース処理

#### Step 3: モード別処理を理解する

各モードの実装を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | sp_BlitzIndex.sql | `sp_BlitzIndex.sql` | コード内で@Mode変数による分岐を確認 |

**主要処理フロー**:
- Mode=0: 診断チェック実行
- Mode=1: サマリー生成
- Mode=2: 使用詳細（@SortOrder適用）
- Mode=3: 不足インデックス出力
- Mode=4: 詳細診断

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

```
sp_BlitzIndex (エントリーポイント)
    │
    ├─ パラメータヘルプ表示 (@Help = 1)
    │
    ├─ パラメータ解析
    │      ├─ @ObjectNameパース
    │      └─ @DatabaseName特定
    │
    ├─ 一時テーブル作成
    │      ├─ #BlitzIndexResults
    │      ├─ #IndexSanity
    │      ├─ #IndexPartitionSanity
    │      ├─ #IndexSanitySize
    │      ├─ #IndexColumns
    │      ├─ #MissingIndexes
    │      └─ #ForeignKeys
    │
    ├─ データ収集
    │      ├─ sys.indexes
    │      ├─ sys.index_columns
    │      ├─ sys.dm_db_index_usage_stats
    │      └─ sys.dm_db_missing_index_*
    │
    └─ モード別処理
           ├─ Mode=0: 診断チェック
           ├─ Mode=1: サマリー
           ├─ Mode=2: 使用詳細
           ├─ Mode=3: 不足インデックス
           └─ Mode=4: 詳細診断
```

### データフロー図

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

パラメータ指定 ──────────▶ sp_BlitzIndex ──────▶ #BlitzIndexResults
                               │                        │
sys.indexes ◀──────────────────┤                        ├──▶ 診断結果
sys.index_columns ◀────────────┤                        │
sys.dm_db_index_usage_stats ◀──┤                        ├──▶ サマリー
sys.dm_db_missing_index_* ◀────┤                        │
sys.dm_db_partition_stats ◀────┘                        └──▶ 出力テーブル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| sp_BlitzIndex.sql | `sp_BlitzIndex.sql` | ソース | メインストアドプロシージャ |
| sp_Blitz.sql | `sp_Blitz.sql` | ソース | sp_BlitzIndexを呼び出す場合あり |
| Install-All-Scripts.sql | `Install-All-Scripts.sql` | スクリプト | 全スクリプトのインストール |
