lang
lang/sql/forbidden/no-cross-join.md
medium
sql-no-cross-join
禁 CROSS JOIN 与 JOIN 缺 ON 子句 — 都会产生笛卡尔积,是性能杀手。Use when 写 SQL / 迁移脚本 / 评审涉及 `no-cross-join` 的 PR。
cross join笛卡尔积cartesian productjoin on性能杀手
paths
**/*.sqlpy/**/*.pybackend/**/*.py
SQL · 禁 CROSS JOIN / 笛卡尔积
规则
禁 CROSS JOIN,禁多表 FROM 而无 JOIN ON 条件(隐式笛卡尔积)。
反例
-- ❌ 显式 CROSS JOIN
SELECT * FROM users CROSS JOIN presentations;
-- ❌ 隐式笛卡尔积(多表 FROM 无 WHERE 连接)
SELECT *
FROM users u, presentations p;
-- 100 用户 × 1000 课件 = 100K 行
-- ❌ JOIN 漏写 ON 条件(被 MySQL 当成 CROSS JOIN)
SELECT *
FROM users u
JOIN presentations p;
正例
-- ✅ 显式 INNER JOIN
SELECT u.name, p.title
FROM users u
INNER JOIN presentations p ON p.owner_id = u.id;
-- ✅ 唯一允许的"笛卡尔积":与小常量表/CTE 交叉
WITH date_series AS (
SELECT '20260501' AS dt UNION SELECT '20260502' UNION ...
)
SELECT u.id, ds.dt FROM users u CROSS JOIN date_series ds;
-- 用于生成补齐数据
Tortoise 中的对应
Tortoise 不会无意产生 CROSS JOIN(API 强制 ON 条件)。但 raw query 时仍需注意。
CI 检测
# 简单 grep
grep -RIn "CROSS JOIN" --include="*.sql" --include="*.py"
# 多表 FROM 无 JOIN 关键字
grep -RIn -P "FROM\s+\w+\s*,\s*\w+" --include="*.sql"
自检
- [ ] 无
CROSS JOIN(特殊场景必须加注释说明意图)? - [ ] 无
FROM a, b多表逗号语法? - [ ] 所有
JOIN都跟ON条件?