什么是索引下推?索引下推是mysql5.6以后添加的,主要用于解决在组合索引场景下查询性能问题。我们在执行explain select时在extra列出现Using index Condition内容,就表示出现了索引下推。索引下推的核心是为了解决回表的次数,提高查询效率。
mysql架构
在说索引下推之前先简单的看一下mysql的架构,索引下推也间接的优化了mysql的架构分层,使各层之间的逻辑更加清晰,如下图:
MySQL从上至下分为以下几层:
- MySQL服务层:包括NoSQL和SQL接口、查询解析器、优化器、缓存和Buffer等组件。
- 存储引擎层:各种插件式的表格存储引擎,实现事务、索引等各种存储引擎相关的特性。
- 文件系统层:读写物理文件。
工作过程
假设我们有如下表结构,
create table student
(
id int auto_increment
primary key,
name varchar(255) null,
age int null,
class_id int null
)
在表中添加如下索引,
create index idx_name_class
on student (name, class_id);
不使用索引下推
在mysql5.6以前不使用索引下推进行查询,整个步骤如下:
第一步,客户端层产生sql查询语句select *From tab1 where name like '张%' and class_id = 1。
第二步,server层接收客户端层的查询语句,通过执行计划分析以后将组合索引中的最左边的索引字段(即:name索引)传递给innodb层。
第三步,innodb层根据最左面的索引从组合索引树(即:idx_name_class索引树)中筛选数据并形成数据范围。
第四步,接着使用数据范围中的内节点的Id字段,从主键索引树中进行回表,找出每个name索引记录对应的完整数据记录,
第五步,接着将该完整的数据结果返回给server层,
第六步,最后server层使用where子条件中剩下的索引(即:class_id=1)对数据范围进行过滤,找到符合class_id=1的记录,
第七步,最后server层将过滤后的结果返回给客户端层。
整个过程如下图所示:
使用索引下推
在mysql5.6以后使用了索引下推优化查询,整个步骤如下:
第一步,客户端层产生sql查询语句select *From tab1 where name like '张%' and class_id = 1。
第二步,server层接收客户端层的查询语句,通过执行计划分析以后将组合索引(即:name like '张%' and class_id = 1)传递给innodb层。
第三步,innodb层根据组合索引的顺序,先使用name索引从组合索引树(即:idx_name_class索引树)中筛选数据并形成数据范围。
第四步,再使用class_id索引从第三步的结果中再次筛选数据。本案例中组合索引有两个字段,如果实际开发中有三个乃至更多的字段将再次进行筛选。
第五步,经过第三步和第四步的筛选最终得出完全符合组合索引条件的数据范围。
第六步,接着使用数据范围中的内节点的Id字段,从主键索引树中进行回表,找出每个组合索引记录(即:主键)对应的完整数据记录,
第七步,接着将该完整的数据结果返回给server层。
第八步,最后server层将结果返回给客户端层。
总结
- 在执行explain select时在extra列出现Using index Condition内容,就表示出现了索引下推。
- 对于innodb引擎来说,索引下推只适用于组合索引(二级索引)。
- 引用子查询的条件不能下推。
参考: