暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

面试官:什么是索引下推?

程序员恰恰 2024-03-23
25
索引下推也被称为索引条件下推 (Index Condition Pushdown)ICP
我们先简单了解一下MySQL大概的架构:

MySQL服务层负责SQL语法解析、生成执行计划等,并调用存储引擎层去执行数据的存储和检索。

索引下推的下推其实就是指将部分上层(服务层)负责的事情(条件过滤),交给了下层(引擎层)去处理。

在没有使用ICP的情况下,MySQL的查询:

  1. 存储引擎读取索引记录;

  2. 根据索引中的主键值,定位并读取完整的行记录;

  3. 存储引擎把记录交给Server层去检测该记录是否满足WHERE条件。

使用ICP的情况下,查询过程:

  1. 存储引擎读取索引记录

  2. 判断条件部分能否用索引中的列来做检查,条件不满足,则处理下一行索引记录;

  3. 条件满足,使用索引中的主键去定位并读取完整的行记录(就是所谓的回表);

  4. 存储引擎把记录交给层,层检测该记录是否满足条件的其余部分。


有了索引下推的优化,在满足一定条件下,存储 引擎层会在回表查询之前对数据进行过滤,可以减少存储引擎回表查询的次数。

实战:

假如有一张表user, 表有四个字段 id,name,level,tool
建立联合索引(name,level)
匹配姓名第一个字为“大”,并且level为1的用户,sql语句为:
select * from user where name like "大%" and level = 1
复制
在5.6之前,执行流程是如下图
根据前面说的“最左前缀原则”,该语句在搜索索引树的时候,只能匹配到名字第一个字是‘大的记录,接下来是怎么处理的呢?
当然是ID 1 、ID4开始,逐个回表,到主键索引上找出相应的记录,再比对level这个字段的值是否符合。
图 1 中,在 (name,level) 索引里,只是按顺序把“name 第一个字是’大’”的记录一条条取出来回表。因此,需要回表 2次。
MySQL 5.6引入了索引下推优化,可以在索引遍历过程中,对索引中包含的字段先做判断,过滤掉不符合条件的记录,减少回表字数。
下面图1、图2分别展示这两种情况。
5.6及之后,执行流程图如下
图 2 跟图 1 的区别是,InnoDB 在 (name,level) 索引内部就判断了 level是否等于1,对于不等于1 的记录,直接判断并跳过。
在我们的这个例子中,只需要对ID 1 、ID4 这两条记录回表取数据判断,就只需要回表 1 次。
使用索引下推后由两次回表变为一次,提高了查询效率。
总结
如果没有索引下推优化(或称ICP优化),
当进行索引查询时,首先根据索引来查找记录,然后再根据where条件来过滤记录;
在支持ICP优化后,MySQL会在取出索引的同时,判断是否可以进行where条件过滤再进行索引查询
也就是说提前执行where的部分过滤操作,在某些场景下,可以大大减少回表次数,从而提升整体性能

---THE END---


文章转载自程序员恰恰,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论