# 画面設計書 107-MaxDOP設定

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおけるSQL ServerのMax Degree of Parallelism（MaxDOP）設定管理機能（Set-DbaMaxDop、Test-DbaMaxDop）の設計仕様を記載する。

### 本画面の処理概要

SQL Serverの並列処理の最大次数（MaxDOP）設定をテスト・変更するためのコマンドラインインターフェースを提供する。MaxDOPはクエリ実行時に使用されるプロセッサ数を制御し、適切な設定がパフォーマンスに重要である。

**業務上の目的・背景**：MaxDOPが不適切に設定されていると、過度な並列処理によるCXPACKET待機やプロセッサリソースの競合が発生し、全体的なパフォーマンスが低下する可能性がある。特にOLTP環境では並列処理のオーバーヘッドが問題となりやすい。本機能により、CPUコア数とNUMAトポロジに基づいた推奨値の確認と設定の自動化が可能である。SQL Server 2016以上ではデータベース単位のMaxDOP設定もサポート。

**画面へのアクセス方法**：PowerShellコンソールから `Test-DbaMaxDop` または `Set-DbaMaxDop` コマンドを実行する。

**主要な操作・処理内容**：
1. MaxDOPのテスト（Test-DbaMaxDop）：現在値と推奨値の比較
2. インスタンスレベル設定（Set-DbaMaxDop）：サーバー全体のMaxDOP設定
3. データベースレベル設定（Set-DbaMaxDop -Database）：SQL Server 2016以上でのデータベース単位設定

**画面遷移**：Test-DbaMaxDopで推奨値を確認し、Set-DbaMaxDopでパイプラインまたは直接指定で設定を適用する流れ。

**権限による表示制御**：Test-DbaMaxDopはsysadmin権限が必要。Set-DbaMaxDopもsysadmin権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 227 | Set-DbaMaxDop | 主機能 | MaxDOPの設定 |
| 250 | Test-DbaMaxDop | 補助機能 | MaxDOPのテスト |

## 画面種別

コマンドラインインターフェース（テスト・設定）

## URL/ルーティング

PowerShellコマンド実行

## 入出力項目

### Test-DbaMaxDop パラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| SqlInstance | DbaInstance[] | 必須 | 対象SQL Serverインスタンス |
| SqlCredential | PSCredential | 任意 | SQL認証情報 |
| EnableException | Switch | 任意 | 例外を有効にする |

### Set-DbaMaxDop パラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | 任意 | 対象SQL Serverインスタンス |
| SqlCredential | PSCredential | 任意 | SQL認証情報 |
| Database | object[] | 任意 | 対象データベース（SQL 2016以上） |
| ExcludeDatabase | object[] | 任意 | 除外データベース（SQL 2016以上） |
| MaxDop | int | 任意 | 設定するMaxDOP値（省略時は推奨値） |
| AllDatabases | Switch | 任意 | 全データベースに適用（SQL 2016以上） |
| InputObject | PSCustomObject | 任意 | Test-DbaMaxDopからのパイプ入力 |
| EnableException | Switch | 任意 | 例外を有効にする |

## 表示項目

### Test-DbaMaxDop 出力プロパティ

| プロパティ名 | 型 | 説明 |
|-------------|-----|------|
| ComputerName | string | コンピュータ名 |
| InstanceName | string | インスタンス名 |
| SqlInstance | string | 完全なインスタンス名 |
| Database | string | データベース名（N/Aまたはデータベース名） |
| DatabaseMaxDop | string/int | データベースレベルMaxDOP（N/Aまたは値） |
| CurrentInstanceMaxDop | int | インスタンスレベルMaxDOP |
| RecommendedMaxDop | int | 推奨MaxDOP値 |
| Notes | string | 設定に関するガイダンスノート |
| InstanceVersion | string | SQLバージョン |
| NumaNodes | int | NUMAノード数 |
| NumberOfCores | int | 論理コア数 |

### Set-DbaMaxDop 出力プロパティ（インスタンスレベル）

| プロパティ名 | 型 | 説明 |
|-------------|-----|------|
| ComputerName | string | コンピュータ名 |
| InstanceName | string | インスタンス名 |
| SqlInstance | string | 完全なインスタンス名 |
| PreviousInstanceMaxDopValue | int | 変更前のMaxDOP値 |
| CurrentInstanceMaxDop | int | 新しいMaxDOP値 |

### Set-DbaMaxDop 出力プロパティ（データベースレベル）

| プロパティ名 | 型 | 説明 |
|-------------|-----|------|
| InstanceName | string | インスタンス名 |
| Database | string | データベース名 |
| PreviousDatabaseMaxDopValue | int | 変更前のデータベースMaxDOP |
| CurrentDatabaseMaxDopValue | int | 新しいデータベースMaxDOP |

## イベント仕様

### 1-Test-DbaMaxDop実行

1. Connect-DbaInstance（MinimumVersion 9）で接続
2. $server.Configuration.MaxDegreeOfParallelism.ConfigValueで現在値取得
3. sys.dm_os_memory_clerksからNUMAノード数取得
4. sys.dm_os_schedulersから論理コア数取得
5. 推奨MaxDOP計算：
   - 単一NUMAノード：コア数またはmax 8
   - 複数NUMAノード（SQL 2016以上）：NUMAノードあたりコア数またはmax 16
   - 複数NUMAノード（SQL 2016未満）：NUMAノードあたりコア数またはmax 8
6. ガイダンスノート設定（MAXDOP=1の特別注意など）
7. SQL 2016以上：各データベースのMaxDopも取得

### 2-Set-DbaMaxDop実行（インスタンスレベル）

1. InputObject未指定時はTest-DbaMaxDopを実行
2. MaxDop未指定時はRecommendedMaxDopを使用
3. Test-SqlSaでsysadmin権限確認
4. $server.Configuration.MaxDegreeOfParallelism.ConfigValueを更新
5. $server.Configuration.Alter()で設定を永続化
6. PreviousInstanceMaxDopValueを含むPSCustomObjectを出力

### 3-Set-DbaMaxDop実行（データベースレベル）

1. SQL 2016（VersionMajor >= 13）確認
2. Database/ExcludeDatabase/AllDatabasesによるフィルタリング
3. $server.Databases[$dbName].MaxDopを更新
4. $server.Databases[$dbName].Alter()で設定を永続化
5. PreviousDatabaseMaxDopValueを含むPSCustomObjectを出力

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Test-DbaMaxDop | sys.dm_os_memory_clerks, sys.dm_os_schedulers | SELECT | システム情報の読み取り |
| Set-DbaMaxDop（インスタンス） | sys.configurations | UPDATE | インスタンスMaxDOP設定の更新 |
| Set-DbaMaxDop（データベース） | sys.database_scoped_configurations | UPDATE | データベースMaxDOP設定の更新 |

### テーブル別更新項目詳細

#### sp_configure経由（インスタンスレベル）

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|-----|-----------------|------|
| UPDATE | max degree of parallelism | 指定値または推奨値 | 即時反映（再起動不要） |

#### ALTER DATABASE SCOPED CONFIGURATION経由（データベースレベル）

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|-----|-----------------|------|
| UPDATE | MAXDOP | 指定値または推奨値 | 即時反映（再起動不要） |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|--------------|----------|
| MSG001 | エラー | "-Database, -AllDatabases and -ExcludeDatabase are mutually exclusive. Please choose only one." | パラメータ競合時 |
| MSG002 | 警告 | "Server '$instance' (v$($server.versionMajor)) does not support Max DOP configuration at the database level." | SQL 2016未満でデータベースレベル設定試行時 |
| MSG003 | エラー | "Not a sysadmin on $instance. Skipping." | 権限不足時 |
| MSG004 | 情報 | "$instance is configured properly. No change required." | 推奨値と一致時 |
| MSG005 | ノート | "Some applications like SharePoint, Dynamics NAV, SAP, BizTalk has the need to use MAXDOP = 1." | MaxDOP=1の場合 |
| MSG006 | ノート | "This is the default setting. Consider using the recommended value instead." | MaxDOP=0の場合 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 接続失敗 | Stop-Functionでエラー出力し、Continueで次のインスタンスへ |
| NUMAノード数取得失敗 | Stop-Functionでエラー出力し、Continueで次のインスタンスへ |
| 論理コア数取得失敗 | Stop-Functionでエラー出力し、Continueで次のインスタンスへ |
| sysadmin権限不足 | Stop-Functionでエラー出力し、Continueで次のインスタンスへ |
| 設定変更失敗 | Stop-Functionでエラー出力し、Continueで次のインスタンスへ |

## 備考

- 設定変更は即時反映（SQL Server再起動不要）
- MaxDOP=0は「無制限」を意味（すべての利用可能なプロセッサを使用）
- MaxDOP=1は並列処理を無効化（SharePoint、NAV、SAP、BizTalk等で推奨）
- SQL 2016以上ではデータベース単位のMaxDOP設定が可能
- NUMA構成に応じた推奨値計算（KB 2806535に基づく）
- MinimumVersion 9（SQL Server 2005以上）が必要

---

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

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

### 推奨読解順序

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

出力オブジェクトの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Test-DbaMaxDop.ps1 | `public/Test-DbaMaxDop.ps1` | 出力オブジェクトの構造（行185-197, 216-228）を確認 |

**読解のコツ**: インスタンスレベルとデータベースレベルの2種類の出力形式を理解する

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Test-DbaMaxDop.ps1 | `public/Test-DbaMaxDop.ps1` | param()ブロック（行87-92）でパラメータ定義を確認 |
| 2-2 | Set-DbaMaxDop.ps1 | `public/Set-DbaMaxDop.ps1` | param()ブロック（行115-127）でパラメータ定義を確認 |

**主要処理フロー**:
1. **行108**: Connect-DbaInstance（MinimumVersion 9）
2. **行114**: MaxDegreeOfParallelism.ConfigValueで現在値取得
3. **行118-119**: NUMAノード数取得（sys.dm_os_memory_clerks）
4. **行126-127**: 論理コア数取得（sys.dm_os_schedulers）

#### Step 3: 推奨値計算ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Test-DbaMaxDop.ps1 | `public/Test-DbaMaxDop.ps1` | 推奨値計算アルゴリズム（行132-163） |

**主要処理フロー**:
- **行134-141**: 単一NUMAノードの場合（コア数 or max 8）
- **行143-162**: 複数NUMAノードの場合
  - SQL 2016以上：NUMAノードあたりコア数 or max 16
  - SQL 2016未満：NUMAノードあたりコア数 or max 8
- **行165-183**: ガイダンスノート設定

#### Step 4: 設定変更ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Set-DbaMaxDop.ps1 | `public/Set-DbaMaxDop.ps1` | インスタンス/データベースレベル設定（行159-281） |

**主要処理フロー**:
- **行135-138**: パラメータ相互排他チェック
- **行166-168**: sysadmin権限確認（Test-SqlSa）
- **行170-196**: SQL 2016以上のデータベースレベル設定分岐
- **行226-230**: インスタンスレベル設定（Configuration.MaxDegreeOfParallelism）
- **行245-252**: データベースレベル設定（Databases[$db].MaxDop）
- **行249-252**: Alter()で永続化

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

```
Test-DbaMaxDop
    |
    +-- Connect-DbaInstance -MinimumVersion 9
    |
    +-- Configuration.MaxDegreeOfParallelism.ConfigValue
    |
    +-- sys.dm_os_memory_clerks (NUMAノード数)
    |
    +-- sys.dm_os_schedulers (論理コア数)
    |
    +-- 推奨値計算
    |      +-- 単一NUMA: min(cores, 8)
    |      +-- 複数NUMA (SQL2016+): min(cores/numa, 16)
    |      +-- 複数NUMA (SQL2016-): min(cores/numa, 8)
    |
    +-- ガイダンスノート設定
    |      +-- MAXDOP=1: SharePoint等の注意
    |      +-- MAXDOP=0: デフォルト設定の注意
    |
    +-- (SQL 2016以上)
           +-- 各データベースのMaxDop取得

Set-DbaMaxDop
    |
    +-- パラメータ相互排他チェック
    |      +-- Database vs AllDatabases vs ExcludeDatabase
    |
    +-- (InputObject未指定時)
    |      +-- Test-DbaMaxDop
    |
    +-- Test-SqlSa (sysadmin権限確認)
    |
    +-- (インスタンスレベル)
    |      +-- Configuration.MaxDegreeOfParallelism.ConfigValue = 値
    |      +-- Configuration.Alter()
    |
    +-- (データベースレベル、SQL 2016以上)
           +-- Databases[$db].MaxDop = 値
           +-- Databases[$db].Alter()
```

### データフロー図

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

SqlInstance ──────▶ Connect-DbaInstance ──────▶ SMO Server Object
                           |
                           v
                    sys.dm_os_memory_clerks
                           |
                           v
                    NumaNodes取得
                           |
                           v
                    sys.dm_os_schedulers
                           |
                           v
                    NumberOfCores取得
                           |
                           v
                    推奨値計算
                           |
                           v
                    PSCustomObject ──────▶ CurrentInstanceMaxDop, RecommendedMaxDop

                    (Set-DbaMaxDop)
                           |
                           v
                    Configuration.Alter() / Databases[].Alter()
                           |
                           v
                    PSCustomObject ──────▶ PreviousMaxDop, CurrentMaxDop
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Set-DbaMaxDop.ps1 | `public/Set-DbaMaxDop.ps1` | ソース | MaxDOP設定 |
| Test-DbaMaxDop.ps1 | `public/Test-DbaMaxDop.ps1` | ソース | MaxDOPテスト |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |
