开发者社区> 三分恶> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

五分钟搞懂MySQL索引下推

简介: 五分钟搞懂MySQL索引下推
+关注继续查看

大家好,我是老三,今天分享一个小知识点——索引下推。

如果你在面试中,听到MySQL5.6”、“索引优化” 之类的词语,你就要立马get到,这个问的是“索引下推”。

什么是索引下推

索引下推(Index Condition Pushdown,简称ICP),是MySQL5.6版本的新特性,它能减少回表查询次数,提高查询效率。

索引下推优化的原理

我们先简单了解一下MySQL大概的架构:

image.png

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

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

我们来具体看一下,在没有使用ICP的情况下,MySQL的查询:

  • 存储引擎读取索引记录;
  • 根据索引中的主键值,定位并读取完整的行记录;
  • 存储引擎把记录交给Server层去检测该记录是否满足WHERE条件。

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

  • 存储引擎读取索引记录(不是完整的行记录);
  • 判断WHERE条件部分能否用索引中的列来做检查,条件不满足,则处理下一行索引记录;
  • 条件满足,使用索引中的主键去定位并读取完整的行记录(就是所谓的回表);
  • 存储引擎把记录交给Server层,Server层检测该记录是否满足WHERE条件的其余部分。

索引下推的具体实践

理论比较抽象,我们来上一个实践。

使用一张用户表tuser,表里创建联合索引(name, age)。

image.png

如果现在有一个需求:检索出表中名字第一个字是张,而且年龄是10岁的所有用户。那么,SQL语句是这么写的:

select * from tuser where name like '张%' and age=10;

假如你了解索引最左匹配原则,那么就知道这个语句在搜索索引树的时候,只能用 ,找到的第一个满足条件的记录id为1。

image.png

那接下来的步骤是什么呢?

没有使用ICP

在MySQL 5.6之前,存储引擎根据通过联合索引找到name likelike '张%' 的主键id(1、4),逐一进行回表扫描,去聚簇索引找到完整的行记录,server层再对数据根据age=10进行筛选

我们看一下示意图:

image.png

可以看到需要回表两次,把我们联合索引的另一个字段age浪费了。

使用ICP

而MySQL 5.6 以后, 存储引擎根据(name,age)联合索引,找到name likelike '张%',由于联合索引中包含age列,所以存储引擎直接再联合索引里按照age=10过滤。按照过滤后的数据再一一进行回表扫描。

我们看一下示意图:

可以看到只回表了一次。

除此之外我们还可以看一下执行计划,看到Extra一列里Using index condition,这就是用到了索引下推。

+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type  | possible_keys | key      | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | tuser | NULL       | range | na_index      | na_index | 102     | NULL |    2 |    25.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-----------------------+

索引下推使用条件

  • 只能用于rangerefeq_refref_or_null访问方法;
  • 只能用于InnoDBMyISAM存储引擎及其分区表;
  • InnoDB存储引擎来说,索引下推只适用于二级索引(也叫辅助索引);

索引下推的目的是为了减少回表次数,也就是要减少IO操作。对于InnoDB聚簇索引来说,数据和索引是在一起的,不存在回表这一说。

  • 引用了子查询的条件不能下推;
  • 引用了存储函数的条件不能下推,因为存储引擎无法调用存储函数。

相关系统参数

索引条件下推默认是开启的,可以使用系统参数optimizer_switch来控制器是否开启。

查看默认状态:

mysql> select @@optimizer_switch\G;
*************************** 1. row ***************************
@@optimizer_switch: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on
1 row in set (0.00 sec)

切换状态:

set optimizer_switch="index_condition_pushdown=off";
set optimizer_switch="index_condition_pushdown=on";


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
索引
索引
19 0
MySQL索引详解(一文搞懂)
索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。
188 0
MySQL聚簇索引和非聚簇索引的理解
MySQL聚簇索引和非聚簇索引的理解
59 0
一张图搞懂MySQL的索引失效
索引对于MySQL而言,是非常重要的篇章。索引知识点也巨多,要想掌握透彻,需要逐个知识点一一击破,今天来先来聊聊哪些情况下会导致索引失效。
1897 0
10、MySQL索引
索引 索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构。类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获取即可。 30 10 ...
837 0
索引
一、索引  在关系数据库中,索引是一种与表有关的数据库结构,它可以使对应于表的SQL语句执行得更快。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。当表中有大量记录时,若要对表进行查询,第一种搜索信息方式是全表搜索,是将所有记录一一取出,和查询条件进行一一对比,然后返回满足条件的记录,这样做会消耗大量数据库系统时间,并造成大量磁盘I/O操作;第二种就是在表中建立索引,然后在索引中找到符合查询条件的索引值,最后通过保存在索引中的ROWID(相当于页码)快速找到表中对应的记录。
861 0
索引
索引的概念类似于图书中提示用的术语索引。一本书中的术语索引可以帮助读者很快找到该术语在书中的具体解释信息。
414 0
+关注
三分恶
一个能文能武的全栈开发~
340
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载