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

一、核心优化技巧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字节,过长的字符串列可使用前缀索引。

七、结尾总结

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

相关推荐
Nontee5 小时前
MySQL 插入冲突了怎么办?两种处理方式入门笔记
数据库·笔记·mysql
devilnumber7 小时前
MySQL 性能优化・诗意化记忆
数据库·mysql·性能优化
宠友信息9 小时前
社区类源码开发实践中的仿小红书系统技术要点分析
java·spring boot·redis·mysql·uni-app·vue·内容运营
Lyra_Infra11 小时前
MySQL Docker 误删恢复:binlog PITR
mysql·docker·命令行
南城以南溫暖如初14711 小时前
从零搭建24小时自助健身系统:技术选型与核心模块实战
java·spring boot·redis·mysql·vue·mybatis
鱼鳞_12 小时前
热门八股-MySQL
数据库·mysql
这个DBA有点耶12 小时前
数据库“家谱”系列之一:关系型数据库的4大核心组件详解
数据库·mysql·架构
Frank_refuel13 小时前
MYSQL【进阶】 -> 索引(了解)
数据库·mysql
l1t13 小时前
DeepSeek总结的DuckDB 如何更快地运行递归 CTE
java·开发语言·数据库·mysql·duckdb
csdn_aspnet16 小时前
mysql 函数、存储过程写法及示例
数据库·mysql·存储过程·函数·function·procedure