意図しないデカルト積 -- CROSS JOINの罠
結合条件の欠落や不正確さが原因でSQLクエリに発生する意図しないデカルト積を特定し修正する方法を学びます。検出テクニックを含みます。
Common Mistakes
詳細な説明
デカルト積とは?
デカルト積は、あるテーブルのすべての行が別のテーブルのすべての行とペアになる場合に発生します。Table Aに1,000行、Table Bに1,000行ある場合、結果は1,000,000行です。CROSS JOINでは意図的ですが、偶然に発生すると壊滅的なバグになります。
一般的な原因
1. ON句の欠落
-- バグ:ON句を忘れた
SELECT o.id, c.name
FROM orders o
JOIN customers c;
-- orders * customers行を生成
2. WHERE句なしのカンマ構文
-- バグ:条件なしの旧式結合
SELECT o.id, c.name
FROM orders o, customers c;
-- 同じデカルト積
3. 間違った結合カラム
-- バグ:非ユニークカラムで結合
SELECT o.id, c.name
FROM orders o
JOIN customers c ON o.status = c.status;
-- 500件の注文と200件の顧客が'active'ステータスを共有している場合、
-- それだけで100,000行が生成される
4. マルチテーブルクエリでの結合の欠落
-- バグ:table Cはどこにも結合されていない
SELECT a.*, b.*, c.*
FROM table_a a
JOIN table_b b ON a.id = b.a_id,
table_c c;
-- table_cは残りとCROSS JOINされる
検出方法
- 行数を確認:結果が予想よりはるかに多い行を持つ場合、デカルト積を疑ってください。
- EXPLAINプラン:プランでインデックス条件なしの
Nested LoopやCross Joinを探してください。 - 経験則:適切な結合は、正当な1対多または多対多リレーションシップがない限り、
MAX(左行, 右行)より多い行を生成すべきではありません。
修正方法
- テーブルをリンクする正しい
ON句を追加する。 - カンマ区切りテーブルの代わりに明示的な
JOIN構文を使用する。 FROM句のすべてのテーブルが少なくとも1つの結合条件に参加していることを確認する。
防止策
- 結合条件の欠落を警告するSQLリンターを使用する。
- 本番データで実行する前に、新しいクエリに対して常に
EXPLAINを実行する。 - カンマ構文ではなく、常に最新の
JOIN ... ON構文のみを使用する。
ユースケース
クエリが予想外に遅い、行数が多すぎる、または重複データが生成される場合に、意図しないデカルト積に注意してください。最も一般的でコストのかかるSQLのミスの1つです。