高频必查的等值字段(如tenant_id、user_id)必须放最左,因B+树查找需从最左列开始连续匹配;跳过则索引失效,范围字段须置右以防阻断后续列使用,ORDER BY/GROUP BY字段需紧接等值条件且顺序方向一致。

WHERE 条件里哪些字段必须放最左
联合索引生效的前提是 WHERE 必须包含最左列,且后续列要连续出现。比如索引 (tenant_id, user_id, status),只有 WHERE tenant_id = ?、WHERE tenant_id = ? AND user_id = ? 或 WHERE tenant_id = ? AND user_id = ? AND status = ? 才能完整走索引;WHERE user_id = ? 或 WHERE status = ? 直接失效。
高频、必查的等值字段(如 tenant_id、user_id)必须放最左——不是因为“它在 SQL 里写得靠前”,而是因为它决定了 B+ 树的查找起点。跳过它,MySQL 就找不到入口。
- 区分度低的字段(如
is_deleted、gender)别放最左,否则树第一层节点太多,实际过滤效率差 - 哪怕
email区分度更高,只要它不总出现在 WHERE 开头(比如只在 20% 查询里出现),就不该抢第一位 - 用
SHOW INDEX FROM table_name查看Cardinality,粗估字段区分度:COUNT(DISTINCT col) / COUNT(*)
范围查询字段为什么不能放最左或中间断开
>、、<code>BETWEEN、LIKE 'abc%' 这类操作会让索引“停在这一列”。例如索引 (a, b, c) 配合 WHERE a = 1 AND b > 10 AND c = 5,MySQL 只能用上 a 和 b 做查找,c = 5 不参与索引查找(可能用于排序或覆盖,但不会缩小扫描范围)。
更危险的是:如果把范围字段放最左,比如 (created_at, status),而查询常是 WHERE created_at > '2025-01-01',那整个索引基本白建——优化器大概率直接走全表扫描。
- 范围字段应放在等值字段之后,且尽量靠右
- 若必须支持
WHERE status = ? AND created_at > ?,优先保证status在左,再补高区分度前缀(如加tenant_id到最左) -
LIKE '%abc'或LIKE '%abc%'会让整个索引前缀失效,别指望它走索引
ORDER BY 和 GROUP BY 字段怎么塞进联合索引
排序和分组字段要“紧接在等值条件之后”,且顺序、方向必须严格一致。比如索引 (a, b, c) 支持 WHERE a = 1 ORDER BY b, c,但不支持 WHERE a = 1 ORDER BY c,也不支持 ORDER BY b DESC, c ASC(方向不一致)。
如果查询是 SELECT * FROM t WHERE a = 1 ORDER BY b,而索引是 (a, c, b),中间插了 c,那 ORDER BY b 就触发 Using filesort——B+ 树里 b 并不连续有序。
- GROUP BY
a, b要加速,索引必须是(a, b)或(a, b, c),不能是(a, c, b) - 写 SQL 时条件顺序不影响是否走索引(优化器会重排),但索引定义顺序决定能否支撑排序
- EXPLAIN 看
Extra字段:出现Using filesort就说明排序没走索引
覆盖索引要不要把 SELECT 字段全加进去
如果查询经常是 SELECT id, name, status FROM t WHERE status = ? ORDER BY create_time,建索引 (status, create_time, id, name) 可以避免回表——查完索引树就拿到全部数据,Extra 显示 Using index。
但要注意:主键自动包含在二级索引中,所以 (status, create_time) 实际已含主键 id,无需重复加 id;而 name 是非主键字段,要覆盖就得显式加上。
- 字段越多,索引体积越大,写入性能越差,别盲目堆字段
- 区分度高的字段优先放前面,覆盖字段放后面——顺序仍服从最左前缀原则
- 用
EXPLAIN的key_len验证实际用了多少列:比如索引 4 列但key_len只显示前 2 列长度,说明后两列因范围/函数/类型转换没生效
真正容易被忽略的,是索引字段顺序一旦定死,就很难动态调整——改顺序等于删重建,线上表可能锁表数分钟。所以设计阶段就得想清楚:哪些条件 100% 出现在 WHERE 开头?哪些排序永远固定方向?哪些字段查得多但区分度低?别等慢查询报警了才回头翻 EXPLAIN。


















