面试题:如何利用联合索引提升性能?

一、核心优化技巧1:遵循最左匹配,合理设计列顺序

1. 核心规则:等值条件列在前,范围条件列在后

联合索引的列顺序直接决定了查询能否利用索引,必须根据查询条件的类型设计:

  • ✅ 正确示例:查询where name='Lily' and age>17,建索引idx(name, age)

  • name是等值条件,先锁定区间,再利用区间内age的有序性快速过滤;

  • ❌ 错误示例:建索引idx(age, name)

  • age是范围条件,锁定区间后name的有序性被破坏,无法利用索引。

2. 面试要点:避免"区分度优先"的误区

很多同学误以为区分度高的列要放前面,其实核心是查询条件的等值/范围类型,区分度仅在等值条件列之间作为次要参考。

二、核心优化技巧2:利用覆盖索引,彻底告别回表

1. 核心原理:查询的所有列都包含在联合索引中,无需回表

InnoDB的二级索引叶子节点存储的是(索引列值 + 主键值),如果查询的所有列都在索引中,MySQL可直接从索引返回数据,无需回表访问聚簇索引,大幅减少IO开销。

2. 实战示例

  • 原SQL(需回表):select * from t where name='Lily' and age=17,索引idx(name, age)

  • select *需要查询所有列,索引中没有其他列,必须回表;

  • 优化后(覆盖索引):select name, age from t where name='Lily' and age=17,索引idx(name, age)

  • 查询的列都在索引中,无需回表,explainExtra列会显示Using index

3. 面试要点:避免使用select *,仅查询必要列

覆盖索引是优化查询性能的核心手段,面试时一定要提到"避免select *,使用覆盖索引减少回表"。

三、核心优化技巧3:利用索引有序性,干掉Using filesort

1. 核心原理:如果order by的列是联合索引的后续列,且前面的列是等值条件,可直接利用索引有序性排序,无需额外文件排序。

2. 实战示例

  • 原SQL(出现Using filesort):select * from t where name like 'L%' order by age,索引idx(name, age)

  • name是范围条件,锁定区间后age的有序性被破坏,MySQL需额外排序;

  • 优化后(无Using filesort):select * from t where name='Lily' order by age,索引idx(name, age)

  • name是等值条件,锁定区间后age是有序的,可直接利用索引排序,无需额外操作。

四、核心优化技巧4:合并冗余索引,减少索引维护开销

1. 核心原理:联合索引的前缀列可替代单列索引,减少索引数量

联合索引idx(a, b)的前缀a是有序的,可替代单列索引idx(a),无需单独创建,减少索引数量的同时,降低写入操作的维护开销(索引越多,写入性能越差)。

2. 实战示例

  • 原索引:idx(name)idx(name, age),两个索引都能用于查询name的场景;

  • 优化后:删除idx(name),仅保留idx(name, age),后者可覆盖前者的所有查询场景,同时减少索引维护开销。

五、核心优化技巧5:配合索引下推(ICP),优化范围查询

1. 核心原理:当联合索引的前导列是范围条件,后续列无法利用索引时,开启ICP可在存储引擎层过滤后续列,减少Server层的过滤开销。

2. 实战示例

  • SQL:select * from t where name like 'L%' and age=17,索引idx(name, age)

  • name是范围条件,age无法利用索引,开启ICP后,存储引擎层可直接用索引中的age值过滤,仅将符合条件的主键传给Server层,减少数据传输开销。

六、避坑指南:这些索引失效场景别踩

❌ 误区1:在索引列上使用函数/运算,导致索引失效

  • 示例:where date_format(create_time, '%Y-%m')='2024-05',可使用虚拟列+索引优化。

❌ 误区2:前导列使用范围条件,导致后续列失效

  • 示例:where a>1 and b=2,索引idx(a,b)a是范围条件,b无法利用索引,可调整为idx(b,a)

❌ 误区3:联合索引总长度超过限制,导致索引创建失败

  • 正解:InnoDB联合索引的总长度不能超过3072字节,过长的字符串列可使用前缀索引。

七、结尾总结

利用联合索引提升性能的核心,是最大化利用索引的有序性,避免回表和额外排序。面试时按这几个技巧回答,再结合业务场景举例,就能拿满分!

相关推荐
Java成神之路-2 小时前
面试题:联合索引的结构
mysql
摇滚侠2 小时前
MySQL 面试题 真正的 offer 偏方 Java 基础 Java 高级
java·数据库·mysql
码上有光2 小时前
MySQL的基础操作——约束(上)——期末快速复习
数据库·mysql·期末复习
無限進步D2 小时前
MySQL 运算符
数据库·mysql
WL_Aurora2 小时前
MySQL 目录结构全解析
数据库·mysql
未若君雅裁11 小时前
MySQL高可用与扩展-主从复制读写分离分库分表
java·数据库·mysql
雨辰AI13 小时前
SpringBoot3 项目国产化改造完整流程|从 MySQL 到人大金仓落地
java·数据库·后端·mysql·政务
神仙别闹17 小时前
基于Java+MySQL实现(GUI)医院管理系统
java·mysql·oracle
TO_WebNow19 小时前
MySQL 索引的相关知识
数据库·mysql