首页/数据/SQL 速查/联合索引的前缀使用规则
性能与执行计划72 条

联合索引的前缀使用规则

复合索引 (a,b,c) 只有从 a 开始连续使用才能有效:跳过前导列、或在中间列用范围,都会截断后续列的索引查找。

SQL 速查数据更新于 2026-10-13

联合索引的前缀规则

复合索引 (a, b, c) 只有在从最左列开始连续使用时才有效:只写 b = ? 用不上这棵索引,写了 a = ? AND c = ? 也只能用上 a 这一列,因为 c 必须等 b 也被使用后才能继续参与定位。某一列一旦使用范围条件,后续列就无法继续用于索引查找。设计索引时把等值条件列放前面、范围列放后面,并尽量让列顺序覆盖更多查询。用 EXPLAIN 的 key_len 可以推断实际用到了前几列。

基本信息

规则从最左列开始连续使用才有效
跳过前导列只写中间或后面的列,索引全部失效
范围截断某列用范围条件后,后续列无法继续用于定位
设计原则等值列在前,范围列在后
验证手段EXPLAIN 的 key_len 推断命中的列数
适用平台MySQL 与 PostgreSQL 的 B 树索引规则一致

典型使用场景

  • 多条件查询建索引:按条件的等值与否决定列顺序
  • 判断现有索引能否复用:核对查询条件是否从最左列开始
  • 优化列表查询:常见的状态加时间组合
  • 调试慢查询:用 key_len 确认只用到了前几列
  • 评估新增索引的必要性:能不能被现有索引覆盖
  • 规范表设计:索引列顺序写进开发约定

示例

示例
ALTER TABLE orders ADD INDEX idx_abc (user_id, status, created_at);

-- 能有效使用索引
SELECT * FROM orders WHERE user_id = 100;
SELECT * FROM orders WHERE user_id = 100 AND status = 'paid';
SELECT * FROM orders WHERE user_id = 100 AND status = 'paid' AND created_at > '2024-01-01';

-- 用不上(未从最左列开始)
SELECT * FROM orders WHERE status = 'paid';
SELECT * FROM orders WHERE created_at > '2024-01-01';

-- 中途列用范围条件:created_at 条件仍可过滤,但不再进入索引定位
SELECT * FROM orders WHERE user_id = 100 AND status > 'p' AND created_at > '2024-01-01';

使用情况对照

查询条件索引用到哪几列说明
a = ?第 1 列有效
a = ? AND b = ?前 2 列有效
a = ? AND b = ? AND c = ?全部 3 列有效
b = ? 或 c = ?未使用未从最左列开始
a = ? AND c = ?只有第 1 列c 被 b 隔断
a = ? AND b > ? AND c = ?前 2 列b 是范围,c 不再参与定位
key_len 是判断命中了前几列的实用手段:把 key_len 与各列的定义长度对照,就能估算实际用到了哪几列。
MySQL 有索引下推(ICP),范围截断后的列条件仍可能在存储引擎层过滤,减少回表次数,但它不等于索引定位,扫描量依旧可观。
查询条件的书写顺序不影响索引使用,真正决定的是索引本身的列顺序,这一点常被误解。

设计要点

  • 先收集高频查询,再按等值条件在前、范围条件在后排列
  • 把区分度高的列放前面,能让索引更快缩小范围
  • 覆盖高频查询的多个条件,避免为每种组合各建一棵索引
  • 定期清理冗余索引:最左前缀相同的索引大多可以合并
  • 新增索引前先用 EXPLAIN 验证查询确实会用到它
  • 索引越多写入越慢,权衡读性能与写成本

易错点

  • 按查询条件的书写顺序随意建索引:列顺序决定可用性,等值列在前通常更通用
  • 忽略范围截断:某列用了范围条件后,后续列不能再靠索引定位,key_len 会提前截止
  • 以为条件写在前面就会被优先使用:决定因素是索引列顺序,不是 SQL 里的书写顺序
  • 为每种条件组合各建一棵索引,写入变慢且冗余索引挤占缓存
  • 只在开发库验证索引效果,小数据量下优化器可能根本不选这棵索引

数据来源与参考

  • MySQL 8.0 Reference Manual · Range Optimization
  • MySQL 8.0 Reference Manual §8.8.2 EXPLAIN Output Format
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌