MySQL多列索引查询优化
1. 单列索引的使用逻辑
如果 a、b、c 是三个独立的单列索引:
- 优化器通常只会选择其中一个索引(通常是选择性最高的索引)进行扫描,然后通过回表(回主键索引)获取完整数据行,再应用剩余条件(
b和c)进行过滤。 - 示例:假设
a的选择性最高(即不同值更多),优化器可能选择a的索引,找到所有满足a条件的行,再逐行检查b和c是否符合条件。 - 执行计划:通过
EXPLAIN查看时,key列会显示实际使用的索引(如a),Extra列可能显示Using where,表示回表后需过滤其他条件。
2. 索引合并(Index Merge)
在特定情况下,MySQL 可能使用 Index Merge Optimization,即同时使用多个索引的交集(AND 条件)或并集(OR 条件):
- 触发条件:需要满足
WHERE中的多个条件可以分别通过不同索引高效过滤。 - 示例:若优化器认为同时使用
a和b的索引更高效,可能通过index_merge_intersection合并结果,再过滤c。 - 执行计划:
type列显示index_merge,key列显示多个索引(如a,b),Extra列显示Using intersect(a,b); Using where。
3. 联合索引(最推荐的方式)
如果经常需要同时查询 a、b、c,最佳实践是创建联合索引:
CREATE INDEX idx_a_b_c ON table_name(a, b, c);
- 执行逻辑:通过联合索引直接按最左前缀(
a → b → c)快速定位数据,无需回表(如果查询仅需索引覆盖的列)。 - 优势:效率远高于单列索引或索引合并,因为索引本身已包含所有条件字段,且顺序符合最左前缀原则。
验证方法:使用 EXPLAIN
通过 EXPLAIN 查看实际执行计划:
EXPLAIN SELECT * FROM table_name WHERE a = 1 AND b = 2 AND c = 3;
- 关键字段解读:
type:访问类型(如ref、index_merge)。key:实际使用的索引。Extra:额外信息(如Using where表示回表后过滤)。
总结
- 单列索引场景:通常只用一个索引,其他条件回表过滤。
- 索引合并场景:可能用多个索引,但需满足优化器策略。
- 最佳实践:优先使用联合索引
(a, b, c),效率最高。
建议根据实际查询模式设计联合索引,并通过 EXPLAIN 验证优化器的选择。
