神奇的 SQL 之 ICP → 索引条件下推
开心一刻

楼主:来,我们先排练一遍
小伙伴们:好
嘿、哈、嚯
楼主:非常好,就是这个节奏,我们开始吧
楼主:啊、啊、啊,疼 ! 你们是不是故意的 ?
回表与覆盖索引
正式讲 ICP 之前了,我们先将相关的概念捋一捋,知道的就当回顾,不知道的就当了解了,这有助于对 ICP 的理解
建个示例表 tbl_index
CREATE TABLE tbl_index (
c1 INT,
c2 INT,
c3 CHAR(1),
PRIMARY KEY(c1),
KEY idx_c2 (c2)
);
覆盖索引
如果 where 条件的列和 select 的列都在一个索引中,通过这个索引就可以完成查询,这就叫就叫覆盖索引;当然,覆盖索引基本针对的是组合索引(InnoDB 的聚簇索引有点特殊,具体可以看下面的图)
针对上面的 tbl_index, select c2 from tbl_index where c2 = 4; 是覆盖索引查询,但是这条 SQL 没有意义,如果我们在 tbl_index 表上增加索引 index idx_c2_c3 (c2,c3) ,那么 select c3 from tbl_index where c2 = 4; 走覆盖索引查询还是很有意义的,那问题又来了,覆盖索引的意义何在 ? 我们往下看
回表
通过某个索引无法直接完成 SQL 查询(where 条件的列和 select 的列不全部存在于任何一个索引中),那么此时需要获取完整的数据记录来完成此次查询,从索引项记录到获取对应的完整数据记录的过程就叫回表;概念可能说的有些抽象,我们结合 MySQL 来看看具体什么是回表
InnoDB 的回表
InnoDB 的索引结构有些特殊,非聚簇索引(二级索引)回表到聚簇索引的过程类似如下

InnoDB的聚簇索引即数据,索引和数据是存在一起的;那么直接走聚簇索引查询的 SQL 是不存在回表一说的,比如 select * from tbl_index where c1 = 10; ,只有从二级索引出发,并且二级索引独自完成不了查询的时候才会回表到聚簇索引完成查询
MyISAM 的回表
有这样一种说法: MyISAM 中的索引都是二级索引 ,其实说的是聚簇索引和二级索引的结构基本一致,只是聚簇索引有个唯一性约束
MyISAM 聚簇索引和二级索引,以及它们的回表过程类似如下

MyISAM 的回表过程指的是根据叶子节点中的数据记录的地址来获取完整记录的过程,无论是聚簇索引还是二级索引都可能存在回表的过程;MyISAM 的回表与 InnoDB 还是有差别的
无论是 InnoDB 的回表还是 MyISAM 的回表,很有可能会造成额外的磁盘 IO,这会严重影响查询效率,覆盖索引的目的就是尽量能够一次完成 SQL 查询,避免有回表过程,从而提高效率
如何确认 MySQL 是进行了覆盖索引查询,还是进行了回表查询 ?
看 MySQL 的执行计划,如果 Extra 中只有 using index 则说明使用了覆盖索引查询,如果 Extra 中出现了 using index condition 或 using index & using where 则说明进行了回表查询
ICP
Index Condition Pushdown,MySQL 5.6 中引入的一种优化策略
那么究竟是将什么从哪 Push Down 到哪,优化了什么?要弄清楚这 4 个问题,我们需要先弄清楚 where 条件的提取与应用,具体可查看:神奇的 SQL 之 WHERE 条件的提取与应用
where 条件会被提取成 3 部分: Index Key,Index Filter,Table Filter ,在 MySQL 5.6 之前,并不区分 Index Filter 与 Table Filter,统统将 Index First Key 与 Index Last Key 范围内的索引记录,回表读取完整记录,然后返回给 MySQL Server 层进行过滤,而在 MySQL 5.6 之后,Index Filter 与 Table Filter 分离,Index Filter 下降到引擎层(InnoDB和MyISAM)的索引层面进行过滤,减少了回表与返回 MySQL Server 层的记录交互开销,提高了 SQL 的执行效率
ICP 优化过程
假设我们有表: tbl_icp
create table tbl_icp (a int primary key, b int, c int, d int, e varchar(50));
create index idx_bcd on tbl_icp(b, c, d);
insert into tbl_icp values (4,3,1,1,'a');
insert into tbl_icp values (1,1,1,2,'d');
insert into tbl_icp values (8,8,7,8,'h');
insert into tbl_icp values (2,2,1,2,'g');
insert into tbl_icp values (5,2,2,5,'e');
insert into tbl_icp values (3,3,2,1,'c');
insert into tbl_icp values (7,4,0,5,'b');
insert into tbl_icp values (6,5,2,4,'f');
若没有使用 ICP,则 SQL 查询类似如下

没有使用 ICP 时,引擎层会将满足 Index Key 范围限制的所有数据记录(示例中一共 6 条)逐条返回给 Server 层,然后由 server 层应用 Index Filter 和 Table Filter (MySQL 5.6 之前不区分 Index Filter 和 Table Filter),最后将满足条件的数据返回给客户端;
若使用 ICP,则 SQL 查询类似如下

使用了 ICP,Server 层会将 Index Filter 下推到引擎层,引擎层在对 Index First Key 与 Index Last Key 范围内的索引项逐条进行过滤的时候,会应用上 Index Filter,对不满足 Index Filter 条件的索引项直接过滤掉,无需回表操作,也无需返回给 Server 层,从而提供执行效率;上图中的索引项: 3 1 1 、 3 2 1 不满足 Index Filter 中的 d != 1 , 4 0 5 不满足 c > 0 ,所以这 3 个索引项无需进行回表操作,也不需要返回给 Server 层
相信到这里,大家对 ICP 的 4 个问题应该就比较清楚了
ICP 的适用条件
虽说 ICP 能提高 SQL 执行效率,但也不是任何情况下都适用的,它只适用于某些情况
1、当 SQL 需要全表访问时,ICP 的优化策略可用于 range, ref, eq_ref, ref_or_null 类型的数据访问方式
2、只适用于 InnoDB 和 MyISAM 两种存储引擎
3、在 InnoDB 中,ICP 只适用于二级索引
ICP 的目的就是为了减少回表导致的磁盘 I/O,而 InnoDB 的聚簇索引的叶子节点存放的就是完整的数据记录,只要索引数据被读到内存了,那么索引项对应的完整数据记录也就读到内存了,那么通过索引项获取数据记录的过程就在内存中进行了,无需进行磁盘 I/O;也就说聚簇索引上应用 ICP,不会减少磁盘 I/O,也就没有使用的意义了
4、不支持覆盖索引
其实和第 3 点一样,因为覆盖索引无需回表,ICP 也就没意义了
5、不支持子查询条件的下推
6、不支持存储过程条件、触发器条件的下推
至于 ICP 的优化效果,取决于在存储引擎内通过 ICP 筛选掉的数据的比例,过滤掉的数据比例大,那就性能提升大,反之则性能提升小
总结
1、索引覆盖与回表
这两个往往是一起来考虑的,因为覆盖索引的目的就是减少因回表产生的磁盘 I/O,从而提高执行效率
在实际应用中,我们往往也需要考虑尽可能用覆盖索引来完成我们的 SQL 查询
2、ICP的四个问题
将什么从哪 Push Down 到哪,优化了什么
将 Index Filter 从 Server 层 Push Down 到了引擎层,减少了因回表产生的磁盘 I/O,也减少了与 Server 层的交互,提高了 SQL 执行效率
3、疑问点
为什么这么明显的优化策略到 MySQL 5.6 才引入,个人感觉很容易就能考虑到呀,MySQL 的开发者们是肿么肥事 ?

可能是楼主在巨人的肩膀上,站着说话不腰疼吧......
参考
Index Condition Pushdown Optimization
神奇的 SQL 之 ICP → 索引条件下推的更多相关文章
- 浅析MySQL中的Index Condition Pushdown (ICP 索引条件下推)和Multi-Range Read(MRR 索引多范围查找)查询优化
本文出处:http://www.cnblogs.com/wy123/p/7374078.html(保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误 ...
- MySQL 中Index Condition Pushdown (ICP 索引条件下推)和Multi-Range Read(MRR 索引多范围查找)查询优化
一.ICP优化原理 Index Condition Pushdown (ICP),也称为索引条件下推,体现在执行计划的上是会出现Using index condition(Extra列,当然Extra ...
- MySQL5.6之Index Condition Pushdown(ICP,索引条件下推)-Using index condition
http://blog.itpub.net/22664653/viewspace-1210844/ -- 这篇博客写的更细,以后看 ICP(index condition pushdown)是mysq ...
- mysql5.6新功能索引条件下推(转载)
原文地址:http://www.cnblogs.com/zengkefu/p/5684101.html 一什么是"索引条件下推" "索引条件下推",称为 Ind ...
- 【mysql优化 2】索引条件下推优化
原文地址:Index Condition Pushdown Optimization 索引条件下推(ICP:index condition pushdown)是mysql中一个常用的优化,尤其是当my ...
- MySQL 优化之 ICP (index condition pushdown:索引条件下推)
ICP技术是在MySQL5.6中引入的一种索引优化技术.它能减少在使用 二级索引 过滤where条件时的回表次数 和 减少MySQL server层和引擎层的交互次数.在索引组织表中,使用二级索引进行 ...
- 神奇的 SQL 之擦肩而过 → 真的用到索引了吗
开心一刻 今天下班,骑着青桔电动车高高兴兴的哼着曲回家,感觉整个世界都是我的 刚到家门口,还未下车,老妈就气冲冲的走过来对我说道:"你表哥就比你大一岁,人家都买了奔驰了,50 多万!&quo ...
- 神奇的 SQL 之扑朔迷离 → ON 和 WHERE,好多细节!
开心一刻 楼主:心都让你吓出来了! 狮王:淡定,打个小喷嚏而已 前情回顾 神奇的 SQL 之 联表细节 → MySQL JOIN 的执行过程(一)中,我们讲到了 3 种联表算法:SNL.BNL 和 I ...
- MySQL--索引条件下推优化
http://blog.163.com/li_hx/blog/static/1839914132015782821512/ 一 什么是“索引条件下推” “索引条件下推”,称为 Index Condit ...
随机推荐
- Python练习五-函数
1.简述普通参数.指定参数.默认参数.动态参数的区别1)普通参数中,有形参和实参,其中形参是定义函数时写的参数,实参是调用函数时传给函数的参数:2)默认参数是在定义函数时,参数设定一个默认值:3)指定 ...
- 用Kinect为听障人士架一座沟通的桥梁
编者按:这是微软亚洲研究院和中国科学院共同进行的一个合作项目,希望通过使用Kinect来帮助提升手语的识别率,从而为听力受损的残障人士(以下简称听障人士)架起一座与外界沟通的桥梁. 文章译自:Digi ...
- layui表格自动对齐
正常情况table应该是这样展示的 但是却展示成了这样 格子没对齐,找了半天原因发现是在table.render中的cols参数多了一个"," 不细心一点真看不出来 正常结构应是 ...
- 执行PHP -m报错Xdebug MUST be loaded as a Zend extension
Xdebug扩展安装后执行PHP -m报错: <br /><b>Warning</b>: Xdebug MUST be loaded as a Zend exten ...
- nginx+php+扩展件安装实践版
一.安装各种软件包 yum -y install wget git vim lrzsz unzip zip gcc make gd-devel bzip2 bzip2-devel libcurl li ...
- AngularJs 中ngModel绑定HTML5 date数据同步问题
以下代码例子中,直接将date类型的input标签与ng-model对应的变量绑定,会出现内存数据和页面数据不一致的问题.虽然AngularJS是双向数据绑定,但是如果用下面的方法,在页面更新date ...
- 用Spring Tool Suite简化你的开发
如果你是一个喜欢用spring的人,你可能会在欣赏spring的强大功能外,对其各样的配置比较郁闷,尤其是相差较大的版本在配置文件方面会存在差异,当然你可以去花不少的时间去网上查找相关的资料,当你准备 ...
- jquery框架概览(一)
参照jQuery 2.0.3版本(http://files.cnblogs.com/files/snoy/jquery-2.0.3.js")来进行的源码分析 从代码的最外层可以看到是一个II ...
- B 小雨的三角形
题目链接:https://ac.nowcoder.com/acm/contest/949/B 思路: 一个找规律题,找到规律就很简单,只剩下代码实现了.规律:第i行去头尾剩下的数的和等于第i-1行去头 ...
- Adam项目展示微软研究院人工智能领域新突破
编者按:在美国时间7月14日举行的2014年微软教育峰会上,Adam项目面对牵上台的3只小狗,一一准确地报出了它们的品种.Adam项目代表了微软研究院在机器学习和人工智能领域的前沿进展.它可不仅仅认得 ...