该用多列索引而非多个单列索引的情况是:查询条件为左前缀匹配(如WHERE a=?、a=? AND b=?等),且优化器默认不启用index_merge;单列索引适用于单独过滤、外键、ORDER/GROUP BY或高基数列;多列索引列序应按等值过滤性强弱降序排列,并用EXPLAIN验证实际使用效果。

什么时候该用多列索引而不是多个单列索引
MySQL 的优化器通常不会同时使用多个单列索引去加速同一个查询(除非启用了 index_merge,但它是例外而非默认行为)。如果你常查 WHERE user_id = ? AND status = ?,建两个单列索引 (user_id) 和 (status) 效果往往不如一个联合索引 (user_id, status)。
关键看查询条件是否「左前缀匹配」:多列索引 (a, b, c) 能加速以下条件:
WHERE a = ?WHERE a = ? AND b = ?WHERE a = ? AND b = ? AND c = ?-
WHERE a = ? AND b IN (?, ?) AND c = ?(c 仍可用)
但无法加速 WHERE b = ? 或 WHERE b = ? AND c = ?(缺少最左列 a),此时索引失效。
单列索引更适合哪些场景
单列索引在以下情况更合适:
- 该列频繁单独出现在
WHERE条件中,且值分布较均匀(如email、order_no) - 作为外键字段,需保证引用完整性(如
user_id在订单表中) - 用于
ORDER BY col或GROUP BY col,且不涉及其他过滤列 - 列基数极高(如 UUID),而组合后区分度没明显提升,建联合索引反而浪费空间
注意:如果已有单列索引 (a),又新建了多列索引 (a, b),那原来的 (a) 索引大概率可以删掉——因为 (a, b) 已能覆盖所有 a 单独查询的需求,还省下一次索引维护开销。
多列索引的列顺序怎么定
顺序不是随便写的,直接影响索引能否命中。核心原则是:「过滤性越强、越常用于等值查询的列放前面」。
BJXSHOP购物管理系统是一个功能完善、展示信息丰富的电子商店销售平台;针对企业与个人的网上销售系统;开放式远程商店管理;完善的订单管理、销售统计、结算系统;强力搜索引擎支持;提供网上多种在线支付方式解决方案;强大的技术应用能力和网络安全系统 BJXSHOP网上购物系统 - 书店版,它具备其他通用购物系统不同的功能,有针对图书销售而进行开发的一个电子商店销售平台,如图书ISBN,图书目录
比如用户表有 status(只有 'active'/'inactive')、created_at(时间戳)、user_id(唯一):
- 查
WHERE status = 'active' AND user_id = 123→ 推荐(user_id, status),因为user_id = ?过滤性最强,能直接定位一行 - 查
WHERE created_at > '2024-01-01' AND status = 'active'→(status, created_at)更好,因为status是等值,created_at是范围;MySQL 只能对多列索引中最左边的等值列之后的第一列用范围扫描
错误示例:(created_at, status) 对 WHERE status = ? 完全无效;对 WHERE created_at > ? AND status = ? 也只能用上 created_at,status 变成表扫描过滤。
如何验证索引是否真的被用了
别猜,用 EXPLAIN 看执行计划:
EXPLAIN SELECT * FROM orders WHERE user_id = 100 AND status = 'paid';
重点关注这几列:
-
key:显示实际使用的索引名 -
key_len:值越大,说明用到的索引列越多(例如key_len=8可能只用了第一列,key_len=12表示前两列都参与了查找) -
rows:预估扫描行数,越小越好 -
Extra:出现Using index表示覆盖索引;出现Using where; Using index是理想状态;若写的是Using where; Using filesort,说明ORDER BY没走索引
容易被忽略的一点:即使 EXPLAIN 显示用了索引,如果 rows 值接近全表行数,说明该索引选择性太差,可能还不如全表扫描——这时候得重新评估列顺序或是否真需要这个索引。









