# 画面設計書 263-無効インデックス検索

## 概要

本ドキュメントは、dbatoolsの無効インデックス検索機能に関する画面設計書です。SQL Serverデータベース内で無効化されているインデックスを識別し、データベースメンテナンスやパフォーマンストラブルシューティングに活用するためのPowerShellコマンドを定義します。

### 本画面の処理概要

本機能は、SQL Serverデータベースをスキャンして無効化されたインデックスを検出し、データベース名、スキーマ名、テーブル名、インデックス名などの詳細情報を返すFind-DbaDbDisabledIndexコマンドを提供します。

**業務上の目的・背景**：無効化されたインデックスは、データ変更時にメンテナンスされないにもかかわらずストレージスペースを消費します。バルク操作中に無効化されたまま再有効化されていないインデックスを特定することは、データベースメンテナンス、パフォーマンストラブルシューティング、ストレージ最適化において重要です。本機能により、クリーンアップ対象または再有効化対象のインデックスを効率的に発見できます。

**画面へのアクセス方法**：PowerShellコンソールから以下のコマンドを実行してアクセスします。
```powershell
Find-DbaDbDisabledIndex -SqlInstance <インスタンス名>
```

**主要な操作・処理内容**：
1. 指定されたSQL Serverインスタンスへの接続
2. 対象データベースの特定（全データベースまたは指定データベース）
3. sys.indexesを使用した無効化インデックスの検索
4. 無効化インデックスの詳細情報（スキーマ、テーブル、インデックス名、タイプ）の取得
5. 結果のオブジェクト出力

**画面遷移**：
- `Connect-DbaInstance`で接続を確立後に実行可能
- パイプライン入力対応（SqlInstanceパラメータ）
- 取得結果は`Export-Csv`等で出力可能

**権限による表示制御**：
- データベースへの接続権限が必要
- sys.tables、sys.schemas、sys.indexes、sys.databasesへのSELECT権限が必要

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 312 | Find-DbaDbDisabledIndex | 主機能 | 無効インデックスの検索 |

## 画面種別

CLI（コマンドラインインターフェース）- PowerShellコマンド

## URL/ルーティング

PowerShellコマンド: `Find-DbaDbDisabledIndex`

## 入出力項目

### パラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | Yes | 対象SQL Serverインスタンス（パイプライン入力対応） |
| SqlCredential | PSCredential | No | 代替認証情報 |
| Database | object[] | No | 対象データベース（ワイルドカード対応） |
| ExcludeDatabase | object[] | No | 除外するデータベース |
| NoClobber | switch | No | ファイルエクスポート時の上書き防止（未実装） |
| Append | switch | No | ファイルエクスポート時の追記モード（未実装） |
| EnableException | switch | No | 例外を有効化 |

## 表示項目

### 出力オブジェクト（System.Data.DataRow）

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DatabaseName | string | 無効インデックスを含むデータベース名 |
| DatabaseId | int | SQL Server内のデータベースID |
| SchemaName | string | インデックスを含むテーブルのスキーマ名 |
| TableName | string | 無効インデックスを含むテーブル名 |
| ObjectId | int | SQL Server内のテーブルオブジェクトID |
| IndexName | string | 無効化されたインデックス名 |
| IndexId | int | テーブル内のインデックスID（0=ヒープ, 1以上=インデックス） |
| TypeDesc | string | インデックスタイプ（CLUSTERED, NONCLUSTERED, HEAP, SPATIAL等） |

## イベント仕様

### 1-Find-DbaDbDisabledIndex実行

1. beginブロックでSQLクエリを定義
2. SqlInstanceパラメータの各インスタンスに対してループ処理
3. Connect-DbaInstanceで接続（MinimumVersion 9 = SQL Server 2005以降）
4. Database指定時は対象データベースをフィルタリング
5. 各データベースに対してクエリを実行
6. 結果が存在する場合はDataRowオブジェクトを出力

### 2-クエリ処理

実行されるT-SQLクエリ:
```sql
SELECT DB_NAME() AS DatabaseName
,d.database_id AS DatabaseId
,s.name AS SchemaName
,t.name AS TableName
,i.object_id AS ObjectId
,i.name AS IndexName
,i.index_id AS IndexId
,i.type_desc AS TypeDesc
FROM sys.tables t
JOIN sys.schemas s ON t.schema_id = s.schema_id
JOIN sys.indexes i ON i.object_id = t.object_id
JOIN sys.databases d ON d.name = DB_NAME()
WHERE i.is_disabled = 1
```

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Find-DbaDbDisabledIndex | sys.tables | SELECT | テーブル情報の取得 |
| Find-DbaDbDisabledIndex | sys.schemas | SELECT | スキーマ情報の取得 |
| Find-DbaDbDisabledIndex | sys.indexes | SELECT | インデックス情報の取得（is_disabled=1） |
| Find-DbaDbDisabledIndex | sys.databases | SELECT | データベース情報の取得 |

本コマンドは読み取り専用操作のみを行い、データベースの変更は行いません。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|--------------|---------|
| MSG001 | エラー | Failure | 接続エラー |
| MSG002 | 情報 | Getting indexes from database '{db}'. | デバッグ/詳細出力時 |
| MSG003 | 情報 | No Disabled indexes found | 無効インデックスが見つからない場合 |
| MSG004 | エラー | Issue gathering indexes | クエリ実行エラー |
| MSG005 | 情報 | There are no databases to analyse. | 対象データベースがない場合 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 接続エラー | Stop-FunctionでConnectionErrorカテゴリのエラーを報告し次のインスタンスへ |
| クエリ実行エラー | Stop-FunctionでInvalidOperationカテゴリのエラーを報告 |
| データベースアクセス不可 | ExcludeDatabase指定またはnullチェックでスキップ |
| 最小バージョン未満 | Connect-DbaInstanceで-MinimumVersion 9を指定（SQL 2005以降） |

## 備考

- SQL Server 2005以降に対応（MinimumVersion 9）
- NoClobberおよびAppendパラメータは現在の関数ロジックでは未実装
- SupportsShouldProcess対応（WhatIf/Confirmパラメータ使用可能）
- is_disabled = 1のインデックスのみを検索対象とする
- ヒープ（index_id = 0）は除外されない（無効化可能な場合は含まれる）

---

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

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

### 推奨読解順序

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

本コマンドが問い合わせるシステムテーブルの関係を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Find-DbaDbDisabledIndex.ps1 | `public/Find-DbaDbDisabledIndex.ps1` | 行107-123のSQLクエリでJOIN構造を確認 |

**読解のコツ**: sys.tables → sys.schemas → sys.indexes → sys.databases の結合関係と、WHERE句のis_disabled = 1フィルターを理解します。

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

beginブロックでのクエリ定義とprocessブロックでの実行フローを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Find-DbaDbDisabledIndex.ps1 | `public/Find-DbaDbDisabledIndex.ps1` | 行106-124のbeginブロック |
| 2-2 | Find-DbaDbDisabledIndex.ps1 | `public/Find-DbaDbDisabledIndex.ps1` | 行125-171のprocessブロック |

**主要処理フロー**:
1. **107-123行**: $sql変数にT-SQLクエリを定義
2. **127-131行**: Connect-DbaInstanceで接続（MinimumVersion 9）
3. **133-137行**: データベースのフィルタリング（Database指定またはIsAccessible）
4. **140-145行**: ExcludeDatabaseのチェックとスキップ
5. **147-158行**: ShouldProcess確認後にExecuteWithResultsでクエリ実行
6. **152-157行**: 結果行の出力

#### Step 3: エラー処理を理解する

接続エラーとクエリ実行エラーの処理を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Find-DbaDbDisabledIndex.ps1 | `public/Find-DbaDbDisabledIndex.ps1` | 行129-131, 163-165のエラー処理 |

**主要処理フロー**:
- **129-131行**: 接続エラー時のStop-Function（-Continue指定で次のインスタンスへ）
- **163-165行**: クエリエラー時のStop-Function（-Target $db指定）

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

```
Find-DbaDbDisabledIndex
    |
    +-- begin block
    |       +-- $sql 変数にT-SQLクエリ定義
    |
    +-- process block
            |
            +-- foreach ($instance in $SqlInstance)
                    |
                    +-- Connect-DbaInstance (MinimumVersion=9)
                    |
                    +-- $server.Databases フィルタリング
                    |       +-- Where-Object Name -in $database
                    |       +-- Where-Object IsAccessible -eq $true
                    |
                    +-- foreach ($db in $databases.name)
                            |
                            +-- ExcludeDatabase チェック
                            |
                            +-- PSCmdlet.ShouldProcess
                            |
                            +-- $server.Databases[$db].ExecuteWithResults($sql)
                                    |
                                    +-- sys.tables
                                    +-- sys.schemas
                                    +-- sys.indexes (is_disabled = 1)
                                    +-- sys.databases
```

### データフロー図

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

SqlInstance          +------------------+
SqlCredential    -->| Connect-Dba      |
                     | Instance         |
                     +--------+---------+
                              |
                              v
Database             +------------------+
ExcludeDatabase  -->| Databases        |
                     | フィルタリング   |
                     +--------+---------+
                              |
                              v
                     +------------------+
                     | ExecuteWith      |---> System.Data.DataRow[]
                     | Results($sql)    |     (無効インデックス情報)
                     +------------------+
                              |
                              v
                     [sys.indexes WHERE is_disabled = 1]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Find-DbaDbDisabledIndex.ps1 | `public/Find-DbaDbDisabledIndex.ps1` | ソース | 無効インデックス検索の主要ロジック |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | 依存 | SQL Server接続処理 |
