# 機能設計書 312-Find-DbaDbDisabledIndex

## 概要

本ドキュメントは、SQL Serverデータベース内の無効化されたインデックスを検出するFind-DbaDbDisabledIndex機能の設計仕様を記載する。

### 本機能の処理概要

Find-DbaDbDisabledIndexは、SQL Serverデータベースをスキャンして無効化されたインデックスを特定し、データベース名、スキーマ名、テーブル名、インデックス名を含む詳細情報を返す機能である。

**業務上の目的・背景**：無効化されたインデックスは、ストレージスペースを消費しながらもデータ変更時のメンテナンス対象とならず、クエリオプティマイザにも使用されない。バルクロード操作やインデックス再構築の前に無効化されたインデックスが、作業完了後に再有効化されずに残っているケースが多い。本機能はこれらの「忘れ去られた」無効化インデックスを発見し、クリーンアップまたは再有効化の判断材料を提供することで、データベースの健全性維持とストレージ最適化に貢献する。

**機能の利用シーン**：本機能は以下のような場面で利用される。
- データベースメンテナンス時の不要インデックス検出
- パフォーマンストラブルシューティング時のインデックス状態確認
- バルクロード後のインデックス再有効化漏れチェック
- データベース移行前の健全性監査
- ストレージスペース最適化のための無効インデックス特定

**主要な処理内容**：
1. 指定されたSQL Serverインスタンスへの接続確立
2. 対象データベースの特定（全データベースまたは指定データベース）
3. sys.indexesビューを使用した無効化インデックスの検索クエリ実行
4. 検索結果の整形と出力

**関連システム・外部連携**：SQL Server Management Objects (SMO)を使用してSQL Serverに接続し、T-SQLクエリでシステムカタログビューを参照する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | インデックス管理 | 主機能 | 無効化インデックスの検出と一覧表示 |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes | 検索対象のSQL Serverインスタンス（複数可） | SQL Server 2005以降 |
| SqlCredential | PSCredential | No | 代替認証資格情報 | Windows/SQL/AD認証サポート |
| Database | object[] | No | 検索対象データベース名（複数可、ワイルドカード対応） | - |
| ExcludeDatabase | object[] | No | 除外するデータベース名（複数可） | - |
| NoClobber | switch | No | 既存ファイル上書き禁止（未実装） | - |
| Append | switch | No | 既存ファイルへの追記（未実装） | - |
| EnableException | switch | No | 例外処理の有効化 | - |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DatabaseName | string | 無効化インデックスを含むデータベース名 |
| DatabaseId | int | データベースの数値ID |
| SchemaName | string | テーブルが属するスキーマ名 |
| TableName | string | インデックスを含むテーブル名 |
| ObjectId | int | テーブルオブジェクトの数値ID |
| IndexName | string | 無効化されたインデックス名 |
| IndexId | int | インデックスの数値ID |
| TypeDesc | string | インデックスタイプ（CLUSTERED、NONCLUSTERED等） |

### 出力先

- PowerShellパイプライン（System.Data.DataRow形式）

## 処理フロー

### 処理シーケンス

```
1. SQLクエリ定義（beginブロック）
   └─ sys.tables、sys.schemas、sys.indexes、sys.databasesを結合するクエリを定義
2. インスタンスループ開始
   └─ 各SqlInstanceに対して処理を実行
3. 接続確立
   └─ Connect-DbaInstanceでSQL Server 2005以降に接続
4. データベース取得
   └─ Database指定時は指定DB、未指定時はアクセス可能な全DB
5. データベースループ
   └─ ExcludeDatabaseでフィルタリング後、各DBでクエリ実行
6. クエリ実行
   └─ ExecuteWithResultsでSQLクエリを実行
7. 結果出力
   └─ 結果行をパイプラインに出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[SQLクエリ定義]
    B --> C[foreach SqlInstance]
    C --> D[Connect-DbaInstance]
    D --> E{接続成功?}
    E -->|No| F[エラー出力, Continue]
    E -->|Yes| G{Database指定?}
    G -->|Yes| H[指定DBをフィルタ]
    G -->|No| I[アクセス可能な全DB取得]
    H --> J{DB数 > 0?}
    I --> J
    J -->|No| K[メッセージ出力]
    J -->|Yes| L[foreach database]
    L --> M{ExcludeDatabaseに含まれる?}
    M -->|Yes| N[スキップ]
    M -->|No| O{ShouldProcess?}
    O -->|Yes| P[ExecuteWithResults]
    P --> Q{結果あり?}
    Q -->|Yes| R[foreach row 出力]
    Q -->|No| S[No Disabled indexes]
    R --> T[次のDB]
    S --> T
    N --> T
    T --> L
    F --> C
    K --> U[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 最小バージョン要件 | SQL Server 2005（バージョン9）以降が必要 | 接続時 |
| BR-002 | アクセス可能DB自動検出 | Database未指定時はIsAccessible=trueのDBを対象 | Database未指定時 |
| BR-003 | 無効化インデックス条件 | is_disabled = 1 のインデックスのみ検出 | 常時 |
| BR-004 | ShouldProcess対応 | -WhatIf, -Confirmスイッチに対応 | 常時 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 無効化インデックス検索 | sys.tables, sys.schemas, sys.indexes, sys.databases | SELECT | カタログビューから無効化インデックス情報を取得 |

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

#### sys.indexes

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | name, object_id, index_id, type_desc | is_disabled = 1 | 無効化インデックスのみフィルタ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ConnectionError | SQL Serverへの接続失敗 | 接続情報と権限を確認 |
| - | InvalidOperation | クエリ実行エラー | データベースアクセス権限を確認 |
| - | MinimumVersion | SQL Server 2005未満 | SQL Server 2005以降にアップグレード |

### リトライ仕様

リトライ機能は実装されていない。エラー発生時はStop-Functionで処理を中断し、-Continueで次のインスタンスまたはデータベースへ進む。

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

本機能は読み取り専用であり、トランザクション管理は不要。READ UNCOMMITTEDレベルでの参照。

## パフォーマンス要件

- 大規模データベースでも効率的に動作するよう、システムカタログビューを使用
- 各データベースに対して1回のクエリ実行で結果を取得

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

- SqlCredentialによる認証情報の安全な受け渡し
- VIEW DATABASE STATE権限が必要
- MFA対応はConnect-DbaInstanceを通じて実現

## 備考

- NoClobber, Appendパラメータは現在未実装
- 出力はSystem.Data.DataRow形式

---

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

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

### 推奨読解順序

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

出力されるDataRowの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Find-DbaDbDisabledIndex.ps1 | `public/Find-DbaDbDisabledIndex.ps1` | .OUTPUTSコメントで出力プロパティを確認 |

**読解のコツ**: ExecuteWithResultsメソッドはDataSetを返し、Tables[0].Rowsでアクセス。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Find-DbaDbDisabledIndex.ps1 | `public/Find-DbaDbDisabledIndex.ps1` | param()ブロック（93-104行目）でパラメータ定義を確認 |

**主要処理フロー**:
1. **93-104行目**: パラメータ定義（SupportsShouldProcess付き）
2. **106-124行目**: beginブロックでSQLクエリ定義
3. **125-171行目**: processブロックでメイン処理

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Find-DbaDbDisabledIndex.ps1 | `public/Find-DbaDbDisabledIndex.ps1` | 107-123行目のSQLクエリ定義 |

**主要処理フロー**:
- **107-123行目**: sys.tables, sys.schemas, sys.indexes, sys.databasesを結合
- **123行目**: WHERE i.is_disabled = 1 で無効化インデックスをフィルタ

#### Step 4: データベースループを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Find-DbaDbDisabledIndex.ps1 | `public/Find-DbaDbDisabledIndex.ps1` | 140-166行目のデータベース処理ループ |

**主要処理フロー**:
- **142-144行目**: ExcludeDatabaseチェック
- **147行目**: ShouldProcessで確認
- **150行目**: ExecuteWithResultsでクエリ実行
- **152-158行目**: 結果の出力

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

```
Find-DbaDbDisabledIndex
    │
    ├─ Connect-DbaInstance
    │      └─ MinimumVersion: 9 (SQL Server 2005)
    │
    └─ Database.ExecuteWithResults($sql)
           └─ T-SQL クエリ実行
```

### データフロー図

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

SqlInstance ───────────▶ Connect-DbaInstance ───▶ Server オブジェクト
        │                                              │
        ▼                                              ▼
Database パラメータ ───▶ データベースフィルタリング ───▶ 対象DB一覧
        │                                              │
        ▼                                              ▼
                                              ExecuteWithResults
                                                       │
                                                       ▼
                                              DataSet.Tables[0].Rows
                                                       │
                                                       ▼
                                              System.Data.DataRow ───▶ パイプライン出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Find-DbaDbDisabledIndex.ps1 | `public/Find-DbaDbDisabledIndex.ps1` | ソース | メイン機能実装 |
| Find-DbaDbDuplicateIndex.ps1 | `public/Find-DbaDbDuplicateIndex.ps1` | ソース | 関連機能（重複インデックス検出） |
| Find-DbaDbUnusedIndex.ps1 | `public/Find-DbaDbUnusedIndex.ps1` | ソース | 関連機能（未使用インデックス検出） |
