复合索引需遵循最左前缀原则,按查询条件顺序设计字段,如CREATE INDEX idx_city_age_gender ON users(city, age, gender),可高效支持WHERE city=’Beijing’ AND age=25查询,且覆盖索引能避免回表,提升性能。

在mysql中使用复合索引(也叫联合索引)可以显著提升多条件查询的性能。关键在于合理设计索引字段顺序,并遵循最左前缀原则,让查询能够有效命中索引。
理解复合索引的结构
复合索引是基于多个列创建的B+树索引,数据按索引列的顺序排序。例如对 (col1, col2, col3) 建立复合索引,B+树首先按 col1 排序,col1 相同的情况下再按 col2 排序,以此类推。
这意味着以下查询可以利用该索引:
- 只查 col1
- 查 col1 和 col2
- 查 col1、col2 和 col3
但以下情况通常无法充分利用索引:
- 只查 col2 或 col3(未包含最左列)
- 查 col1 和 col3(跳过中间列 col2)
创建合适的复合索引
根据实际查询语句设计索引。比如有如下查询:
select * FROM users WHERE city = ‘Beijing’ AND age = 25 AND gender = ‘M’;
可以创建复合索引:
CREATE INDEX idx_city_age_gender ON users(city, age, gender);
这个索引能完全匹配查询条件,执行时可快速定位数据。
字段顺序很重要。一般把选择性高(即值更唯一)或经常用于过滤的字段放在前面。例如 age 比 gender 选择性更高,更适合放前面。
避免索引失效的常见问题
即使建立了复合索引,某些写法会导致索引无法使用:
- 避免在索引列上做函数操作:如 WHERE YEAR(create_time) = 2024,应改为范围查询
- 避免隐式类型转换:字符串字段用数字查询会导致全表扫描
- 模糊查询注意位置:LIKE ‘abc%’ 可用索引,LIKE ‘%abc’ 不行
- 正确使用范围查询:复合索引中范围查询(>, 10 AND c=3,c 的条件无法走索引
利用覆盖索引减少回表
如果查询所需字段都在复合索引中,MySQL可以直接从索引中获取数据,无需回表查询主键索引,这种称为“覆盖索引”。
例如:
SELECT city, age FROM users WHERE city = ‘Beijing’ AND age = 25;
若存在 (city, age) 索引,则整个查询可在索引中完成,效率更高。
基本上就这些。设计复合索引时结合查询模式,注意最左前缀和字段顺序,就能有效提升查询速度。


