1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PostgreSQL JOINアルゴリズムの直感理解とデータ量別パフォーマンス比較【金融システム夜間バッチ向け】

Last updated at Posted at 2025-10-04

金融システムの夜間バッチでは、大量データのJOINで処理が遅くなることがあります。
本記事では、**JOINの種類と内部アルゴリズム(Nested Loop / Hash Join / Merge Join)**を直感的に整理し、データ量別のパフォーマンスを比較します。

JOINとは?

SQLでいう JOIN は「複数のテーブルを条件で組み合わせて1つの結果を作る操作」

例:

SELECT *
FROM transactions t
JOIN customers c ON t.customer_id = c.customer_id;

JOIN = 目的(結合したい)

実際にどう結合するかはアルゴリズム次第(手段)

JOINの内部アルゴリズム

PostgreSQLの主要アルゴリズムは3種類:

アルゴリズム イメージ 計算量 ポイント
Nested Loop Join
外側テーブル1行ずつ、内側テーブルを探索 O(n×m) 小規模向き、大きいと爆発

Hash Join
小さいテーブルをハッシュ化、もう片方を順番に照合 O(n+m) 小テーブルはメモリに乗る必要あり、メモリ不足でspill

Merge Join
両方をソートして順番にマージ O(n log n + m log m)(ソート込み) ソート済みなら高速&安定、大規模向き

アルゴリズムごとの処理イメージ

Nested Loop Join
外側 = 「順番に1行ずつ見るテーブル」
内側 = 「外側の行に合わせて検索するテーブル」

小さいテーブル×大きいテーブルならOK
大きいテーブル同士だと二重ループで爆発

Hash Join
小さいテーブルを ハッシュ化(メモリ上に展開)
大きいテーブルを1行ずつ照合
メモリ不足時は spill(ディスク退避) が発生し遅くなる

Merge Join
両方を結合キーでソート
順番に比較しながら結合
計算量は O(n log n + m log m)、ソート済みなら O(n+m)
大規模データでも安定して高速

データ量別パフォーマンス比較

データ量-少ない
Nested Loop 高速、シンプル
Hash Join 高速、ほぼO(n+m)
Merge Join ソートコストがあるのでNested Loopより遅い場合も

データ量-多い
Nested Loop 遅い、二重ループで爆発
Hash Join 高速(小テーブルがメモリに乗る場合)
Merge Join 高速&安定、ソート済みならO(n+m)

金融システム夜間バッチの実務ポイント:
小規模データ → Nested Loopで十分
中規模〜大規模 → Hash Join、高速化のためwork_memやハッシュサイズに注意
大規模・ソート済み → Merge Joinで安定

用語整理

用語 意味
JOIN(結合) 複数のテーブルを条件で組み合わせるSQL操作(目的)
Nested Loop / Hash / Merge JOINを実行する内部アルゴリズム(手段)
マージ(merge) Merge Join内部で「順番に照合して結合する」処理
work_mem PostgreSQL がソート・Hash Join・GROUP BYなどの一時作業に使うメモリ量。小さいとディスクに一時書き出し(spill)される
spill work_mem に入りきらないデータを 一時的にディスクに書き出すこと。処理は続くが遅くなる

実務で意識するポイント

①JOIN前に絞り込み → 不要な行を減らす
②インデックス設計 → JOINキーやWHERE句に必須
③EXPLAINで実行計画確認
EXPLAIN (ANALYZE, BUFFERS) SELECT ...

SELECT *
FROM transactions t
JOIN customers c ON t.customer_id = c.customer_id;

得られる情報:
どのテーブル・インデックスが使われたか
内部JOINアルゴリズム(Nested Loop / Hash / Merge)
実行時間
ディスクI/Oの回数(shared hit, read, dirtied, written)

④Hash Joinのspill対策 → work_mem設定
⑤Merge Join活用 → 両方ソート済みデータは大量でも安定

まとめ

Nested Loop = 二重ループ、小規模向き
Hash Join = 小テーブルを辞書化して高速検索
Merge Join = 両方ソート済みなら順番にマージ、高速&安定

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?