# 機能設計書 402-Clear-DbaPlanCache

## 概要

本ドキュメントは、SQL Serverのプランキャッシュにおいて単一使用のアドホック・準備済みプランがメモリ閾値を超えた場合にクリアする`Clear-DbaPlanCache`機能について記述する。

### 本機能の処理概要

**業務上の目的・背景**：SQL Serverの動的SQLやパラメータ化されていないクエリを使用するアプリケーションでは、単一使用のプランがプランキャッシュに蓄積し、メモリ圧迫を引き起こすことがある。この「プランキャッシュの肥大化」は、パフォーマンス低下の一般的な原因である。本機能は、Get-DbaPlanCacheで取得した情報に基づき、閾値を超えた場合にのみプランキャッシュをクリアすることで、手動でのDMV確認とDBCCコマンド実行のプロセスを自動化する。

**機能の利用シーン**：
- プランキャッシュの肥大化によるメモリ圧迫が発生している場合
- 定期メンテナンスの一環としてプランキャッシュを最適化する場合
- 動的SQLを多用するアプリケーション環境の管理
- パフォーマンス問題のトラブルシューティング時

**主要な処理内容**：
1. Get-DbaPlanCacheによる現在のプランキャッシュサイズ取得（または直接パイプライン入力）
2. 単一使用のアドホック・準備済みプランのメモリ使用量と閾値の比較
3. 閾値超過時のみ`DBCC FREESYSTEMCACHE('SQL Plans')`を実行
4. 閾値未満の場合はクリアせずにステータス報告

**関連システム・外部連携**：Get-DbaPlanCacheコマンドとパイプライン連携が可能。外部システムとの連携はない。

**権限による制御**：DBCCコマンドの実行にはALTER SERVER STATE権限またはsysadminロールが必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | コマンドライン | 主画面 | PowerShellコンソールからの直接実行 |

## 機能種別

データ操作（キャッシュクリア） / 条件付き実行

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | 対象のSQL Serverインスタンス | DbaInstanceParameter型による検証 |
| SqlCredential | PSCredential | No | SQL Server認証用の資格情報 | PowerShell資格情報オブジェクト |
| Threshold | int | No | プランキャッシュクリアの閾値（MB）、デフォルト100MB | 整数値 |
| InputObject | object[] | No | Get-DbaPlanCacheからのパイプライン入力 | プランキャッシュオブジェクト |
| EnableException | switch | No | 例外処理を有効化 | - |
| WhatIf | switch | No | 実行せずに処理内容を表示 | - |
| Confirm | switch | No | 実行前に確認を求める | - |

### 入力データソース

- PowerShellコマンドライン入力
- Get-DbaPlanCacheからのパイプライン入力（InputObject）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverが稼働するコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全修飾SQL Serverインスタンス名 |
| Size | string | プランキャッシュサイズ（単位付き表示） |
| Status | string | 処理結果（"Plan cache cleared"または"Plan cache size below threshold (X)"） |

### 出力先

PowerShellパイプライン（PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. パラメータ処理
   └─ SqlInstance指定時: Get-DbaPlanCacheを呼び出してInputObjectに追加
   └─ パイプライン入力時: InputObjectとして受信

2. 各プランキャッシュ結果に対してループ処理
   └─ MBプロパティとThresholdを比較

3. 閾値判定と処理分岐
   └─ 閾値以上の場合:
      └─ Connect-DbaInstanceで接続
      └─ DBCC FREESYSTEMCACHE('SQL Plans')実行
      └─ Status = "Plan cache cleared"
   └─ 閾値未満の場合:
      └─ Status = "Plan cache size below threshold (X)"

4. 結果オブジェクト出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{SqlInstance指定?}
    B -->|Yes| C[Get-DbaPlanCache呼び出し]
    C --> D[InputObjectに追加]
    B -->|No| D
    D --> E{各結果でループ}
    E --> F{MB >= Threshold?}
    F -->|Yes| G{ShouldProcess?}
    G -->|Yes| H[Connect-DbaInstance]
    H --> I{接続成功?}
    I -->|No| J[Stop-Function -Continue]
    J --> E
    I -->|Yes| K[DBCC FREESYSTEMCACHE実行]
    K --> L[Status = Plan cache cleared]
    L --> M[PSCustomObject出力]
    F -->|No| N{ShouldProcess?}
    N -->|Yes| O[Status = Below threshold]
    O --> P[PSCustomObject出力]
    P --> E
    M --> E
    G -->|No| E
    N -->|No| E
    E -->|ループ終了| Q[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 閾値判定 | MBプロパティが閾値以上の場合のみクリア実行 | 各プランキャッシュ結果に対して |
| BR-002 | デフォルト閾値 | 閾値のデフォルト値は100MB | Threshold未指定時 |
| BR-003 | 全SQLプランクリア | 閾値超過時はSQL Plans全体をクリア | 閾値超過時 |

### 計算ロジック

- 閾値比較: `$result.MB -ge $Threshold`

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

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

| 操作 | 対象 | 操作種別 | 概要 |
|-----|------|---------|------|
| キャッシュクリア | SQL Plans cache | DELETE（内部） | DBCCコマンドによるプランキャッシュの全クリア |

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

#### sys.dm_exec_cached_plans（参照元）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| 参照 | usecounts = 1 | 単一使用プラン | Get-DbaPlanCacheで取得 |
| 参照 | objtype = 'Adhoc', 'Prepared' | アドホック・準備済みプラン | Get-DbaPlanCacheで取得 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ConnectionError | SQL Serverへの接続失敗 | Stop-Functionで処理継続 |
| - | ExecutionError | DBCC FREESYSTEMCACHE実行失敗 | 例外として伝播 |

### リトライ仕様

自動リトライなし。

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

DBCCコマンドは暗黙的なトランザクション内で実行される。ロールバック不可。

## パフォーマンス要件

- 閾値チェックは軽量な比較処理
- キャッシュクリア自体は瞬時に完了するが、後続のクエリコンパイルに影響

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

- ALTER SERVER STATE権限またはsysadminロールが必要
- SqlCredentialパラメータでSQL認証を使用可能

## 備考

- Kimberly Tripps (SQLSkills)のブログ記事に基づいた実装
- Get-DbaPlanCache、Find-DbaInstanceと組み合わせた活用が推奨
- キャッシュクリア後は、頻繁に使用されるクエリの再コンパイルが発生する

---

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

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

### 推奨読解順序

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

入力オブジェクト（Get-DbaPlanCacheの出力）と出力オブジェクトの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Clear-DbaPlanCache.ps1 | `public/Clear-DbaPlanCache.ps1` | 106-112行目、116-122行目の出力オブジェクト定義 |

**読解のコツ**: InputObjectはGet-DbaPlanCacheの出力を想定しており、MBプロパティで閾値比較を行う。

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

処理の起点となる関数定義とパラメータを特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Clear-DbaPlanCache.ps1 | `public/Clear-DbaPlanCache.ps1` | 1-90行目のヘルプドキュメントとパラメータ定義 |

**主要処理フロー**:
1. **82-90行目**: パラメータ定義
2. **84行目**: SqlInstanceはオプション（パイプライン入力を優先可能）
3. **86行目**: Thresholdのデフォルト値100を定義
4. **87-88行目**: InputObjectパラメータでパイプライン入力受付

#### Step 3: 前処理と入力統合を理解する

SqlInstance指定時の前処理ロジック。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Clear-DbaPlanCache.ps1 | `public/Clear-DbaPlanCache.ps1` | 91-94行目のprocess開始部分 |

**主要処理フロー**:
- **92-94行目**: SqlInstance指定時はGet-DbaPlanCacheを呼び出してInputObjectに追加

#### Step 4: メイン処理ロジックを理解する

閾値判定とキャッシュクリア処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Clear-DbaPlanCache.ps1 | `public/Clear-DbaPlanCache.ps1` | 96-126行目のメインループ |

**主要処理フロー**:
- **97行目**: 閾値比較 `$result.MB -ge $Threshold`
- **105行目**: DBCCコマンド実行
- **114行目**: 閾値未満時のステータス設定

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

```
Clear-DbaPlanCache
    │
    ├─ Get-DbaPlanCache (SqlInstance指定時)
    │      └─ プランキャッシュ情報取得
    │
    ├─ Connect-DbaInstance (閾値超過時)
    │      └─ SQL Server接続確立
    │
    └─ $server.Query() (SMOメソッド)
           └─ DBCC FREESYSTEMCACHE実行
```

### データフロー図

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

SqlInstance ─────────────▶ Get-DbaPlanCache ──────▶ InputObject
        または                      │
InputObject(パイプライン) ─────────┘
                                    │
                                    ▼
Threshold ──────────────▶ 閾値比較 (MB >= Threshold)
                                    │
                    ┌───────────────┴───────────────┐
                    ▼                               ▼
            閾値以上                           閾値未満
                    │                               │
                    ▼                               ▼
        Connect-DbaInstance              Status = "Below threshold"
                    │                               │
                    ▼                               ▼
        DBCC FREESYSTEMCACHE           PSCustomObject出力
                    │
                    ▼
        Status = "Plan cache cleared"
                    │
                    ▼
        PSCustomObject出力 ─────────────────────▶ パイプライン出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Clear-DbaPlanCache.ps1 | `public/Clear-DbaPlanCache.ps1` | ソース | メイン機能実装 |
| Get-DbaPlanCache.ps1 | `public/Get-DbaPlanCache.ps1` | ソース | プランキャッシュ情報取得（関連機能） |
| Clear-DbaPlanCache.Tests.ps1 | `tests/Clear-DbaPlanCache.Tests.ps1` | テスト | Pesterユニットテスト |
