初めてデータ増大時の負荷テストをやる際のメモ

# 負荷テスト（データ増大時）を実施するときに考えるべきこと・知っておくべきこと

## はじめに

この記事では、**システムの負荷テストにおける「データ増大時」に特化**して取り扱います。  
**同時接続数の増加やトラフィックの集中**といった「システムトラフィックの増大」に関する負荷テストについては本記事の対象外とします。
あくまで **データの件数・容量が増加した際に発生する負荷とその対策** に焦点を当てます。

---

## 基本的な観点

### テストの目的を明確にする
データ増大時の負荷テストには以下のような目的が考えられます：

- 大量データがDB（データベース）やストレージに与える影響を調査
- クエリのパフォーマンス劣化の検出
- キャッシュの効き具合やI/Oボトルネックの洗い出し
- アプリケーションがデータスケールにどこまで耐えられるかの確認

---

## データスケーリングの考え方

### データ量の増加シナリオ

"plaintext
初期状態 → 10万件 → 100万件 → 1000万件 → 1億件
"

段階的にデータを増加させることで、**どのタイミングで性能劣化や障害が発生するか**を評価します。

---

### 妥当なデータ件数の決定方法

#### 元となる情報：

- **要件定義時のユーザー数・操作頻度**
- **運用実績から取得した月次・年次のデータ増加量**

#### 例：

- 月間契約データが20,000件増加する場合
- バッチ処理が1日1回 とすると 1回あたりの対象件数が約667件になります
- 累積データが5年で1,200,000件 → 全体規模を反映したテストも必要です。
- ユーザーごとの処理があるのであれば、ユーザー人数をテーブルの総数で割った平均値の3〜5倍程度の負荷テストをひとまず行うのが良いかと思います。

#### 結合対象件数の考え方

- メインテーブルに対して1:Nの関係で履歴や詳細情報がある場合、結合対象は **「月次増加数 × 関連数」** と計算できます。
  - 例：契約 × 請求明細（1:12） → 20,000件/月 × 12件 = 240,000件/月
- JOIN対象が履歴テーブルである場合、JOIN件数は**総量の50%以上**になることもあります。

---

## IO処理に関する負荷ポイント

| 要因 | 内容 |
|------|------|
| **複数テーブルJOIN** | 主にデータ量が増えると最も影響を受けやすい。インデックスや結合条件の最適化が不可欠 |
| **インデックス不使用** | 誤った条件・関数利用による全件スキャン発生 |
| **一時テーブル生成** | GROUP BYやサブクエリで発生。I/O増加の原因 |
| **ファイルI/O** | CSVエクスポート・ログ書き込み・バックアップ等も考慮

---

## JOIN処理の流れについて

① テーブルA（契約）      ② テーブルB（請求明細）
+---------+              +---------+
| 契約ID  |              | 明細ID  |
| ユーザID|              | 契約ID  |
| 契約日  |              | 金額    |
+---------+              +---------+
      ↓                       ↓
   スキャン                  スキャン
     │                         │
     └─────┐           ┌──────┘
           ▼           ▼
      ③ 結合条件に基づいて「照合（Nested Loop / Hash Join等）」
           ▼
      ④ 結果セットを構築（マッチした行を結合）
           ▼
      ⑤ 結果を返す・ソート・グルーピングなど

| 処理段階 | 負荷ポイント | 説明 |
|----------|---------------|------|
| **①②スキャン** | **全件スキャンが発生** | インデックスが効かないと全行を見る必要あり。件数が多いと激重。 |
| **③照合（JOIN）** | **アルゴリズム次第で爆発** | 特にNested Loop Joinは「1件ずつ照合」なので、片方が100万件だと負荷増大しやすい。 |
| **④結果構築** | **JOIN後の行数が膨らむ** | 1:NのNが多いと、それだけ結合行が増える（例：契約1件に対し明細12件 → 12倍）。 |
| **⑤追加処理（ORDER/GROUP BY）** | **一時テーブルが作られることも** | JOIN後に更に並び替え・集計をするとメモリ/IO消費が大きくなる。 |

| アルゴリズム | 特徴 | 向いてるケース | 負荷感 |
|--------------|------|----------------|--------|
| **Nested Loop Join** | 片方の行ごとにもう片方を探す | 件数が少ない | **重め（特に大規模データでは）** |
| **Hash Join** | 一方をハッシュテーブル化 | 中〜大規模データ | **中程度（メモリ消費多）** |
| **Merge Join** | 並び順を利用 | 並び順が揃っている | **速い（ソート済み前提）** |

## ページング処理の有無による負荷テストの必要性判断

ページング（ページ単位での表示）実装があるかどうかは、**負荷テストの対象範囲とデータ件数**に大きく影響します。

### 負荷テストが必要な画面の条件

| 判定基準 | 対応 |
|----------|------|
| **ページングなし（全件表示）** | 高負荷発生のリスク大 → テスト必須。表示件数×JOIN件数が高負荷要因に |
| **ページングあり（1ページ20〜50件）** | 表示件数が制限されていれば、データ増加による表示影響は限定的。ただし、**ページ数が増えることでDBへの負荷は蓄積**するため注意 |
| **エクスポート処理（全件対象）** | ページングがあっても全件を扱う処理は対象とする必要あり |

---

## 負荷テスト計測方法（Chrome DevTools編）

### Step 1：Chrome DevToolsを開く

1. テスト対象のページをChromeで開く  
2. 右クリック → [検証] もしくは `F12` キーで DevTools を起動

### Step 2：ネットワーク・キャッシュを無効化

1. 「Network」タブを開く  
2. 「Disable cache（キャッシュを無効化）」にチェックを入れる（※ DevToolsを開いている間のみ有効）

### Step 3：パフォーマンスの記録を開始

1. 「Performance」タブを開く  
2. 上部の「●（Record）」ボタンを押して記録開始  
3. テスト対象ページをリロード（`Ctrl+R` or `F5`）  
4. ページ表示完了後、記録を停止

→ ローディング時間、各フェーズ（HTML取得・JS処理・DOM構築など）が可視化されます

### Step 4：指標の確認ポイント

- **FCP（First Contentful Paint）**: 最初に何かが表示されたタイミング  
- **LCP（Largest Contentful Paint）**: 一番大きな要素（画像や見出し）が表示されたタイミング  
- **TTI（Time to Interactive）**: 完全に操作可能になるまでの時間  
- **Long Tasks**: JSの重い処理があればグラフ上に赤線が表示されます

→ これらの指標で「体感的な遅さ」の原因を特定できます

### Step 5：ネットワーク制限を使ってシミュレーション

- Networkタブ上部の「No throttling」→「Slow 3G」や「Fast 3G」を選択  
- CPU負荷のシミュレーションも「Performance」タブで設定可能（右上歯車アイコン → CPU Throttling）

→ **低スペック環境やモバイル通信環境での表示速度を再現可能**

---

## パフォーマンス指標（メトリクス）の取得方法と注意点

### 実務的な集計指標

| 指標 | 内容 |
|------|------|
| **平均値** | 全体の傾向把握 |
| **中央値（p50）** | 異常値の影響を受けにくい |
| **p95 / p99** | 一部リクエストの遅延傾向を把握（JOINや不均一データに起因する高負荷を検出するためには有効） |

> **補足1：p95/p99はトラフィックの多い環境でよく使われる統計値ですが、データ増大時にも、JOINや特定条件で遅くなるケースの検出に役立ちます。**

> **補足2：p95/p99のような統計値は十分なリクエスト件数が前提となるため、**  
> **自動化されたツール（JMeter, k6, Datadog等）での計測を前提としています。**  
> 手動テストではこれらの指標は基本的に扱えず、**平均値・最大値・最小値の観察が現実的な範囲です。**

---

## まとめ

- 本記事は**データ増大に伴う処理負荷**に特化し、**トラフィック増大は対象外**としました。
- **テスト対象データ量は要件定義と運用実績から逆算**し、JOIN件数やページングの有無に応じて負荷評価を行う必要があります。
- ページングの有無や全件エクスポート処理の有無によって、**負荷テストの対象とすべき画面の判断基準**を明確に持ちましょう。
- **p95/p99などの統計値は自動化環境での使用が前提**であり、手動環境では平均・最大・最小の組み合わせで評価します。
- Chrome DevToolsを活用すれば、**体感的な遅さの要因分析やUX評価も手軽に実施**できます。

---

## 参考リンク

- [Apache JMeter公式サイト](https://jmeter.apache.org/)
- [k6公式サイト（Grafana製）](https://k6.io/)
- [Google Lighthouse公式](https://developer.chrome.com/docs/lighthouse/)
- [Web Vitals公式](https://web.dev/vitals/)
- [MDN Web Docs - Performance API](https://developer.mozilla.org/ja/docs/Web/API/Performance)
- [PostgreSQL EXPLAIN公式](https://www.postgresql.org/docs/current/using-explain.html)
- [MySQL EXPLAIN公式](https://dev.mysql.com/doc/refman/8.0/en/explain-output.html)
- [Chrome DevTools公式](https://developer.chrome.com/docs/devtools/)