复合索引应遵循最左前缀原则,将高选择性、高频查询及排序字段前置;例如索引(a, b, c)支持a、a+b、a+b+c查询,但不支持单独b或跳过b的a+c;选择性可通过COUNT(DISTINCT col)/COUNT(*)评估,越接近1越好;如查询WHERE user_id = 123 ORDER BY create_time DESC,则建索引(user_id, create_time)可避免额外排序;同时避免冗余索引,已有(a,b,c)则无需(a,b),需定期用EXPLAIN检查索引使用情况。

复合索引的顺序直接影响查询性能,优化顺序的核心是遵循“最左前缀匹配”原则,并结合实际查询条件来设计。合理的顺序能显著提升查询效率,减少全表扫描和临时排序。
理解最左前缀原则
MySQL在使用复合索引时,必须从索引的最左边列开始匹配,中间不能跳过。例如,索引 (a, b, c) 可以支持以下查询:
- WHERE a = 1
- WHERE a = 1 AND b = 2
- WHERE a = 1 AND b = 2 AND c = 3
但无法有效利用该索引进行:
- WHERE b = 2(缺少a)
- WHERE c = 3(缺少a和b)
- WHERE a = 1 AND c = 3(跳过b)
因此,把最常用于过滤或选择性高的字段放在前面更合理。
选择高选择性的字段靠前
选择性是指字段中唯一值的比例。选择性越高,过滤效果越好。比如“性别”字段只有男/女,选择性低;而“用户ID”或“手机号”选择性高。
建议将选择性高的字段放在复合索引的左侧,这样能更快缩小结果集。
可以通过以下SQL评估字段选择性:
SELECT COUNT(DISTINCT column_name) / COUNT(*) FROM table_name;结果越接近1,选择性越高。优先把这类字段放在索引前面。
考虑查询频率和排序需求
除了选择性,还要看字段在查询中的使用频率。如果某个字段几乎每个查询都会用到,即使选择性一般,也应尽量前置。
本文档主要讲述的是lucene索引优化;这篇文章主要介绍了如何提高Lucene的索引速度。介绍的大部分思路都是很容易尝试的,当然另外一部分可能会加大你程序的复杂度。所以请确认索引速度确实很慢,而且很慢的原因确实是因为Lucene自身而造成的;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
同时,如果查询中有 ORDER BY 或 GROUP BY,尽量让索引顺序与这些子句一致,避免额外的排序操作。
例如:
SELECT * FROM orders WHERE user_id = 123 ORDER BY create_time DESC;那么建立索引 (user_id, create_time) 就很合适,既能快速定位数据,又能利用索引完成排序。
避免冗余和过度索引
不要为每个查询都创建独立的复合索引。多个相似索引会增加写操作开销,并占用更多存储。
比如已有索引 (a, b, c),就不需要再单独建 (a, b)。但 (b, a) 是不同的,不能替代。
定期审查执行计划(EXPLAIN),确认索引是否被正确使用,及时删除未命中或低效的索引。
基本上就这些。关键是从实际查询出发,结合选择性、过滤频率和排序需求来安排字段顺序,不是固定规则,而是动态优化过程。









