复合键连接
复合键连接指多列共同构成连接键,ON 里要逐列相等。它比单列连接更容易出错:漏写某一列不会报错,只会把条件放宽,结果行数翻倍或出现错配。被驱动表上的复合索引也要按同样的列序设计才能命中。
基本信息
| 写法 | 所有键列都要在 ON 里配对 |
|---|---|
| 索引 | 被驱动表按同样列序建复合索引,最左前缀可命中 |
| 常见错误 | 漏列时条件放宽,行数放大且不易察觉 |
| 类型要求 | 两侧键列的类型与字符集要一致 |
| 适用平台 | MySQL 与 PostgreSQL 通用 |
典型使用场景
- 按「仓库加区域」匹配库存
- 多租户场景按租户加业务键关联
- 分库分表后按分片键连接
- 关联表按两个外键同时连接
- 排查连接后行数突然翻倍的问题
示例
示例
-- 复合键连接:两列都要配对
SELECT a.*, b.name
FROM stock a
JOIN warehouse b
ON b.warehouse_id = a.warehouse_id
AND b.region_code = a.region_code;
-- 对应的复合索引:列序要与连接条件一致
ALTER TABLE warehouse ADD INDEX idx_wh_region (warehouse_id, region_code);
-- 漏列反例:只写一半会放宽条件,结果行数放大
SELECT COUNT(*) FROM stock a
JOIN warehouse b ON b.warehouse_id = a.warehouse_id; -- 缺少 region_code检查清单
| 检查项 | 正确做法 | 出错后果 |
|---|---|---|
| ON 里的键列 | 全部配对,一列不少 | 条件放宽,结果行数放大 |
| 复合索引列序 | 与连接条件列序一致 | 最左前缀不匹配,索引失效 |
| 列类型 | 两侧类型与字符集一致 | 索引失效或隐式转换带来错配 |
| 统计信息 | 关注多列组合的基数 | 估算偏差导致选错连接顺序 |
复合键只写一半是最隐蔽的错误:查询能正常执行、结果看着也像对的,只有和预期总数对比才会发现行数被放大。
复合索引的列序要跟着连接条件走:两列都是等值比较时,把查询里最常见的过滤列放前面,兼顾命中与排序。