join必须指定on条件,否则产生笛卡尔积;left join中右表过滤条件须写在on而非where;on中多条件需用括号明确优先级;join字段类型和索引必须匹配。

JOIN 必须指定 ON 条件,否则结果是笛卡尔积
不写 ON 或 USING 的 JOIN 会把左表每一行和右表每一行都配一遍,数据量稍大就爆炸。比如左表 1 万行、右表 1 万行,结果就是 1 亿行——不是报错,而是查不动、内存溢出、超时。
-
INNER JOIN和LEFT JOIN都必须跟ON,哪怕字段名相同也不能省略 - 别信“字段名一样就能自动关联”,SQL 标准里没有这回事
- 如果真想用字段名隐式匹配,得用
USING (id),但仅限两边字段名完全一致且类型兼容
LEFT JOIN 后 WHERE 条件写错位置会导致变 INNER JOIN
这是最常踩的坑:把本该放在 ON 里的右表过滤条件,误写进 WHERE。例如想查“所有用户及其订单(含无订单用户)”,但加了 WHERE order.status = 'paid',结果没订单的用户全被干掉了——因为 WHERE 是在 JOIN 完成后才执行,此时右表字段为 NULL,NULL = 'paid' 为 false,整行被剔除。
- 右表的筛选条件,要写在
ON里:LEFT JOIN orders ON users.id = orders.user_id AND orders.status = 'paid' - 左表的筛选条件,可以放
WHERE,也可以放ON,语义一致 - 不确定时,先用
EXPLAIN看执行计划,确认是否真的保留了左表空匹配行
ON 条件里混用 AND 和 OR 容易逻辑错乱
ON 是布尔表达式,但很多人当成“多个条件并列”来写,忽略运算优先级。比如 ON a.id = b.user_id AND b.type = 'A' OR b.type = 'B' 实际等价于 (a.id = b.user_id AND b.type = 'A') OR b.type = 'B',导致大量非预期关联。
- 多条件混合时,一律用括号明确分组:
ON (a.id = b.user_id) AND (b.type IN ('A', 'B')) - 避免在
ON中用OR关联不同逻辑分支;真需要,拆成两个LEFT JOIN或用UNION - 字符串比较注意大小写和空格:
TRIM(b.code) = TRIM(a.code)比直接=更稳妥
JOIN 性能差?先看驱动表和索引是否匹配
数据库优化器通常选小表做驱动表,但若右表关联字段没索引,即使左表只有 10 行,每次也要全表扫右表——10 × 右表行数。更糟的是,JOIN 字段类型不一致(比如 INT 对 VARCHAR),会强制类型转换,索引失效。
- 确保
ON两侧字段类型完全一致,尤其注意id是BIGINT还是INT - 在右表的关联字段上建索引,例如
CREATE INDEX idx_orders_user_id ON orders(user_id) - 用
EXPLAIN看type是否为ref或eq_ref;如果是ALL,说明没走索引











