# 機能設計書 315-Get-DbaHelpIndex

## 概要

本ドキュメントは、SQL Serverデータベースから包括的なインデックスおよび統計情報を取得するGet-DbaHelpIndex機能の設計仕様を記載する。

### 本機能の処理概要

Get-DbaHelpIndexは、SQL Server DMVとシステムテーブルを照会して、パフォーマンス分析、インデックスメンテナンス計画、最適化機会の特定のための詳細なインデックスおよび統計情報を返す機能である。

**業務上の目的・背景**：データベースパフォーマンスの最適化において、インデックスの状態把握は最も重要な作業の一つである。本機能は、インデックスの構造情報（キーカラム、包含カラム、フィルター条件）とランタイムメトリクス（読み取り回数、更新回数、最終使用日時）を組み合わせることで、インデックスの健全性を包括的に把握できる。これにより、未使用インデックスの特定、過度に使用されるインデックスの発見、メンテナンスが必要なインデックスの優先順位付けが可能となる。

**機能の利用シーン**：本機能は以下のような場面で利用される。
- インデックスチューニング作業の基礎データ収集
- 定期的なインデックスヘルスチェック
- クエリパフォーマンス問題の調査
- データベース移行時のインデックス棚卸
- 統計情報の鮮度確認と更新計画の策定
- フラグメンテーション分析と再構築計画

**主要な処理内容**：
1. SQL Serverインスタンスへの接続
2. 対象データベースとテーブルの特定
3. バージョン別のT-SQLクエリを使用したインデックス/統計情報取得
4. オプションに応じた統計情報、データ型、フラグメンテーション情報の追加
5. 整形された結果の出力

**関連システム・外部連携**：SQL Server Management Objects (SMO)を使用してSQL Serverに接続し、sys.indexes、sys.dm_db_index_usage_stats、sys.dm_db_stats_propertiesなどのDMVとシステムカタログビューを参照する。

**権限による制御**：対象データベースへのVIEW DATABASE STATE権限が必要。SQL Server 2005（バージョン9）以降で動作するが、一部の統計情報はSQL 2005では制限される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | インデックス管理 | 主機能 | インデックス情報の詳細表示 |

## 機能種別

データ検索 / インデックス分析

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 検索対象のSQL Serverインスタンス | SQL Server 2005以降 |
| SqlCredential | PSCredential | No | 代替認証資格情報 | Windows/SQL/AD認証サポート |
| Database | object[] | No | 検索対象データベース名（複数可） | - |
| ExcludeDatabase | object[] | No | 除外するデータベース名（複数可） | - |
| ObjectName | string | No | 特定テーブル名（schema.table形式可） | - |
| IncludeStats | switch | No | 統計オブジェクトも含める | - |
| IncludeDataTypes | switch | No | カラムのデータ型情報を含める | - |
| IncludeFragmentation | switch | No | フラグメンテーション情報を含める（処理時間増加） | - |
| InputObject | Microsoft.SqlServer.Management.Smo.Database[] | No | Get-DbaDatabaseからのパイプライン入力 | - |
| Raw | switch | No | 数値を書式なしで返す | - |
| EnableException | switch | No | 例外処理の有効化 | - |

### 入力データソース

- SQL Serverインスタンスへの直接接続
- Get-DbaDatabaseからのパイプライン入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverホストのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なインスタンス名 |
| Database | string | データベース名 |
| Object | string | schema.table形式のオブジェクト名 |
| Index | string | インデックス名（統計行は空） |
| Statistics | string | 統計名（インデックス行はnull） |
| IndexType | string | インデックスタイプ（PRIMARY KEY、UNIQUE等の修飾子付き） |
| KeyColumns | string | キーカラム（DESC付き、データ型オプション） |
| IncludeColumns | string | 包含カラム（なければ空） |
| FilterDefinition | string | フィルター条件（なければ空） |
| FillFactor | int | フィルファクター（0-100） |
| DataCompression | string | 圧縮タイプ（Row/Page/ColumnStore） |
| IndexReads | string/int | 読み取り回数（Raw時は数値） |
| IndexUpdates | string/int | 更新回数（Raw時は数値） |
| Size | string/dbasize | サイズ（KB、Raw時はdbasize） |
| IndexRows | string/int | 行数（Raw時は数値） |
| IndexLookups | string/int | ルックアップ回数（Raw時は数値） |
| MostRecentlyUsed | DateTime | 最終使用日時（未使用時はnull） |
| StatsSampleRows | int | 統計サンプル行数 |
| StatsRowMods | int | 統計更新後の変更行数 |
| HistogramSteps | int | ヒストグラムステップ数 |
| StatsLastUpdated | DateTime | 統計最終更新日時 |
| IndexFragInPercent | string/decimal | フラグメンテーション率（IncludeFragmentation時のみ） |

### 出力先

- PowerShellパイプライン（PSCustomObject形式）

## 処理フロー

### 処理シーケンス

```
1. パラメータ処理（beginブロック）
   └─ テーブル条件、フラグメンテーション条件、統計条件の設定
2. SQLクエリ構築
   └─ SQL 2005用とSQL 2008+用の2種類のクエリを構築
3. インスタンスループ
   └─ 各SqlInstanceに対してConnect-DbaInstanceを実行
4. データベースループ
   └─ Get-DbaDatabaseでデータベース一覧を取得
5. クエリ実行
   └─ バージョンに応じたクエリをdb.Queryで実行
6. 結果処理
   └─ 各行をPSCustomObjectに変換、書式設定を適用
7. 結果出力
   └─ パイプラインに出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[パラメータ処理]
    B --> C[SQLクエリ構築]
    C --> D[foreach SqlInstance]
    D --> E[Connect-DbaInstance]
    E --> F[Get-DbaDatabase]
    F --> G[foreach database]
    G --> H{Version >= 10?}
    H -->|Yes| I[SizesQuery使用]
    H -->|No| J[SizesQuery2005使用]
    I --> K[db.Query実行]
    J --> K
    K --> L[foreach row]
    L --> M[MostRecentlyUsed処理]
    M --> N{Raw指定?}
    N -->|Yes| O[数値をそのまま]
    N -->|No| P[書式設定適用]
    O --> Q[PSCustomObject作成]
    P --> Q
    Q --> R[パイプライン出力]
    R --> L
    L --> G
    G --> D
    D --> S[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 最小バージョン要件 | SQL Server 2005（バージョン9）以降が必要 | 接続時（MinimumVersion 10） |
| BR-002 | SQL 2005統計制限 | ObjectName未指定時はStatsSampleRows等がnull | SQL 2005使用時 |
| BR-003 | 1900年判定 | MostRecentlyUsedが1900年の場合はnullに変換 | 常時 |
| BR-004 | フラグメンテーション負荷 | IncludeFragmentation指定時は処理時間が大幅増加 | IncludeFragmentation指定時 |
| BR-005 | 統計除外 | IncludeStats未指定時は統計のみの行を除外 | デフォルト |

### 計算ロジック

```sql
-- インデックス読み取り回数
IndexReads = user_seeks + user_scans + user_lookups

-- インデックスサイズ（KB）
SizeKB = (SUM(in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count) * 8192) / 1024  -- クラスタ化
SizeKB = (SUM(used_page_count) * 8192) / 1024  -- 非クラスタ化
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| インデックス情報取得 | sys.indexes, sys.index_columns, sys.columns, sys.dm_db_index_usage_stats, sys.dm_db_partition_stats, sys.partitions, sys.stats, sys.stats_columns, sys.dm_db_stats_properties | SELECT | インデックスと統計の詳細情報を取得 |
| フラグメンテーション取得 | sys.dm_db_index_physical_stats | SELECT | DETAILEDモードでフラグメンテーション情報取得 |

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

#### sys.dm_db_stats_properties

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | last_updated, rows_sampled, modification_counter, steps, rows | OUTER APPLY | SQL 2008+のみ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ConnectionError | SQL Serverへの接続失敗 | 接続情報と権限を確認 |
| - | DatabaseNotAccessible | データベースがアクセス不可 | データベース状態を確認 |
| - | QueryError | クエリ実行エラー | データベース権限を確認 |

### リトライ仕様

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

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

本機能は読み取り専用であり、トランザクション管理は不要。READ UNCOMMITTEDで実行。

## パフォーマンス要件

- 基本クエリは効率的なCTE構造
- IncludeFragmentationはDETAILEDモードで負荷が高い
- OPTION (RECOMPILE)でプランキャッシュ汚染を防止

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

- SqlCredentialによる認証情報の安全な受け渡し
- VIEW DATABASE STATE権限が必要

## 備考

- SQL 2005ではDBCC SHOW_STATISTICSを使用して統計情報を取得（ObjectName指定時のみ）
- Rawオプションでdbasizeオブジェクトを返す

---

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

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

### 推奨読解順序

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

出力されるオブジェクトの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaHelpIndex.ps1 | `public/Get-DbaHelpIndex.ps1` | .OUTPUTSコメント（87-122行目）で出力プロパティを確認 |

**読解のコツ**: デフォルト出力とRaw出力で型が異なることに注意。

#### Step 2: SQLクエリを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaHelpIndex.ps1 | `public/Get-DbaHelpIndex.ps1` | 225-591行目（SizesQuery - SQL 2008+用） |
| 2-2 | Get-DbaHelpIndex.ps1 | `public/Get-DbaHelpIndex.ps1` | 596-1041行目（SizesQuery2005） |

**主要処理フロー**:
- **@IndexUsageStats**: 使用統計を一時テーブルに格納
- **@StatsInfo**: 統計情報を一時テーブルに格納
- **cteIndexCols**: インデックスカラム情報を集約
- **cteResults**: 最終結果を構築
- **AllResults**: インデックスと統計を統合

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaHelpIndex.ps1 | `public/Get-DbaHelpIndex.ps1` | 1077-1139行目の結果処理ループ |

**主要処理フロー**:
- **1078-1081行目**: MostRecentlyUsedの1900年判定
- **1094-1115行目**: プロパティマッピングと書式設定
- **1121-1130行目**: Raw指定時とデフォルトの分岐

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

```
Get-DbaHelpIndex
    │
    ├─ Connect-DbaInstance
    │      └─ MinimumVersion: 10
    │
    ├─ Get-DbaDatabase
    │
    └─ Database.Query($indexesQuery)
           └─ T-SQL クエリ実行（バージョン別）
```

### データフロー図

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

SqlInstance ───────────▶ Connect-DbaInstance ───▶ Server オブジェクト
        │                                              │
        ▼                                              ▼
Database/ObjectName ───▶ Get-DbaDatabase ─────────▶ 対象DB一覧
        │                                              │
        ▼                                              ▼
IncludeStats/          ───▶ クエリ条件設定 ─────────▶ 実行クエリ
IncludeFragmentation          │
IncludeDataTypes              │
        │                      ▼
        │               Database.Query()
        │                      │
        ▼                      ▼
Raw ────────────────▶ 結果書式設定 ─────────────▶ PSCustomObject
                                                       │
                                                       ▼
                                              パイプライン出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaHelpIndex.ps1 | `public/Get-DbaHelpIndex.ps1` | ソース | メイン機能実装 |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | データベース取得（依存先） |
| Find-DbaDbUnusedIndex.ps1 | `public/Find-DbaDbUnusedIndex.ps1` | ソース | 関連機能（未使用インデックス検出） |
| Find-DbaDbDuplicateIndex.ps1 | `public/Find-DbaDbDuplicateIndex.ps1` | ソース | 関連機能（重複インデックス検出） |
