http://blog.itpub.net/22664653/viewspace-1210844/ -- 这篇博客写的更细,以后看

ICP(index condition pushdown)是mysql利用索引(二级索引)元组和筛字段在索引中的where条件从表中提取数据记录的一种优化操作。ICP的思想是:存储引擎在访问索引的时候检查筛选字段在索引中的where条件(pushed index condition,推送的索引条件),如果索引元组中的数据不满足推送的索引条件,那么就过滤掉该条数据记录。ICP(优化器)尽可能的把index condition的处理从server层下推到storage engine层。storage engine使用索引过过滤不相关的数据,仅返回符合index condition条件的数据给server层。也是说数据过滤尽可能在storage engine层进行,而不是返回所有数据给server层,然后后再根据where条件进行过滤。使用ICP(mysql 5.6版本以前)和没有使用ICP的数据访问和提取过程如下(插图来在MariaDB Blog):

优化器没有使用ICP时,数据访问和提取的过程如下:

1)    当storage engine读取下一行时,首先读取索引元组(index tuple),然后使用索引元组在基表中(base table)定位和读取整行数据。

2)    sever层评估where条件,如果该行数据满足where条件则使用,否则丢弃。

3)    执行1),直到最后一行数据。

优化器使用ICP时,server层将会把能够通过使用索引进行评估的where条件下推到storage engine层。数据访问和提取过程如下:

1)    storage engine从索引中读取下一条索引元组。

2)    storage engine使用索引元组评估下推的索引条件。如果没有满足wehere条件,storage engine将会处理下一条索引元组(回到上一步)。只有当索引元组满足下推的索引条件的时候,才会继续去基表中读取数据。

3)    如果满足下推的索引条件,storage engine通过索引元组定位基表的行和读取整行数据并返回给server层。

4)    server层评估没有被下推到storage engine层的where条件,如果该行数据满足where条件则使用,否则丢弃。

而使用ICP时,如果where条件的一部分能够通过使用索引中的字段进行评估,那么mysql server把这部分where条件下推到storage engine(存储引擎层)。存储引擎通过索引元组的索引列数据过滤不满足下推索引条件的数据行。

索引条件下推的意思就是筛选字段在索引中的where条件从server层下推到storage engine层,这样可以在存储引擎层过滤数据。由此可见,ICP可以减少存储引擎访问基表的次数和mysql server访问存储引擎的次数。

注意一下ICP的使用条件:

  1. 只能用于二级索引(secondary index)。
  2. explain显示的执行计划中type值(join 类型)为range、 ref、 eq_ref或者ref_or_null。且查询需要访问表的整行数据,即不能直接通过二级索引的元组数据获得查询结果(索引覆盖)。
  3. ICP可以用于MyISAM和InnnoDB存储引擎,不支持分区表(5.7将会解决这个问题)。

 

ICP的开启优化功能与关闭

MySQL5.6可以通过设置optimizer_switch([global|session],dynamic)变量开启或者关闭index_condition_push优化功能,默认开启。

mysql > set optimizer_switch=’index_condition_pushdown=on|off’

用explain查看执行计划时,如果执行计划中的Extra信息为“using index condition”,表示优化器使用的index condition pushdown。

在mysql5.6以前,还没有采用ICP这种查询优化,where查询条件中的索引条件在某些情况下没有充分利用索引过滤数据。假设一个组合索引(多列索引)K包含(c1,c2,…,cn)n个列,如果在c1上存在范围扫描的where条件,那么剩余的c2,…,cn这n-1个上索引都无法用来提取和过滤数据(不管不管是唯一查找还是范围查找),索引记录没有被充分利用。即组合索引前面字段上存在范围查询,那么后面的部分的索引将不能被使用,因为后面部分的索引数据是无序。比如,索引key(a,b)中的元组数据为(0,100)、(1,50)、(1,100) ,where查询条件为 a < 2 and b = 100。由于b上得索引数据并不是连续区间,因为在读取(1,50)之后不再会读取(1,100),mysql优化器在执行索引区间扫描之后也不再扫描组合索引其后面的部分。

表结构定义如下:

1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE `person` (
`person_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`postadlcode` int(11) DEFAULT NULL,
`age` tinyint(4) DEFAULT NULL,
`first_name` varchar(45) NOT NULL,
`last_name` varchar(45) NOT NULL,
`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`person_id`),
KEY `idx_p_a` (`postadlcode`,`age`),
KEY `idx_f_l` (`first_name`,`last_name`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8

关闭ICP优化,Extra信息为“Using Where”

1
2
3
4
5
6
7
mysql> set optimizer_switch = "index_condition_pushdown=off";
mysql> explain select  *   from person  where postadlcode between 300000 and 400000 and age > 40;
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table  | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | person | range | idx_p_a       | idx_p_a | 7       | NULL |   21 | Using where |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-------------+

开启ICP之后,Extra信息为“Using Index Condition”

1
2
3
4
5
6
7
mysql> set optimizer_switch = "index_condition_pushdown=on";
mysql> explain select  *   from person  where postadlcode between 300000 and 400000 and age > 40;
+----+-------------+--------+-------+---------------+---------+---------+------+------+-----------------------+
| id | select_type | table  | type  | possible_keys | key     | key_len | ref  | rows | Extra                 |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-----------------------+
|  1 | SIMPLE      | person | range | idx_p_a       | idx_p_a | 7       | NULL |   21 | Using index condition |
+----+-------------+--------+-------+---------------+---------+---------+------+------+-----------------------+

 

MySQL5.6之Index Condition Pushdown(ICP,索引条件下推)-Using index condition的更多相关文章

  1. 浅析MySQL中的Index Condition Pushdown (ICP 索引条件下推)和Multi-Range Read(MRR 索引多范围查找)查询优化

    本文出处:http://www.cnblogs.com/wy123/p/7374078.html(保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误 ...

  2. MySQL 中Index Condition Pushdown (ICP 索引条件下推)和Multi-Range Read(MRR 索引多范围查找)查询优化

    一.ICP优化原理 Index Condition Pushdown (ICP),也称为索引条件下推,体现在执行计划的上是会出现Using index condition(Extra列,当然Extra ...

  3. 8.2.1.5 Engine Condition Pushdown Optimization 引擎条件下推优化

    8.2.1.5 Engine Condition Pushdown Optimization 引擎条件下推优化 这种优化改善了直接比较在一个非索引列和一个常量比较的效率. 在这种情况下, 条件是 下推 ...

  4. 神奇的 SQL 之 ICP → 索引条件下推

    开心一刻 楼主:来,我们先排练一遍 小伙伴们:好 嘿.哈.嚯 楼主:非常好,就是这个节奏,我们开始吧 楼主:啊.啊.啊,疼 ! 你们是不是故意的 ? 回表与覆盖索引 正式讲 ICP 之前了,我们先将相 ...

  5. 【mysql优化 2】索引条件下推优化

    原文地址:Index Condition Pushdown Optimization 索引条件下推(ICP:index condition pushdown)是mysql中一个常用的优化,尤其是当my ...

  6. MySQL 之 Index Condition Pushdown(ICP)

    简介 Index Condition Pushdown (ICP)是MySQL 5.6 版本中的新特性,是一种在存储引擎层使用索引过滤数据的一种优化方式. 当关闭ICP时,index 仅仅是data ...

  7. mysql5.6新功能索引条件下推(转载)

    原文地址:http://www.cnblogs.com/zengkefu/p/5684101.html 一什么是"索引条件下推" "索引条件下推",称为 Ind ...

  8. MySQL 优化之 ICP (index condition pushdown:索引条件下推)

    ICP技术是在MySQL5.6中引入的一种索引优化技术.它能减少在使用 二级索引 过滤where条件时的回表次数 和 减少MySQL server层和引擎层的交互次数.在索引组织表中,使用二级索引进行 ...

  9. MySQL中Index Condition Pushdown(ICP)优化

    在MySQL 5.6开始支持的一种根据索引进行查询的优化方式.之前的MySQL数据库版本不支持ICP,当进行索引查询是,首先根据索引来查找记录,然后在根据WHERE条件来过滤记录.在支持ICP后,My ...

随机推荐

  1. uvaoj 133 - The Dole Queue(逻辑,环形队列数数)

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  2. Python3.6+selenium3.8+Firefox5.7 环境搭建

    大家好,我是阿哲,本人是从php转岗过来学习测试的一名小菜! 在学习selenium过程中,发现运行selenium有很多的问题. 我们在利用pip install selenium 安装的最新版后, ...

  3. 树莓派怎么连接无线网wifi?

    没有显示器的同学,想要连接无线网,一定非常苦恼,前面教会了大家远程登录图形界面,下面我将教会大家:在没有图形界面的情况下,怎么连接树莓派WiFi.同样还是利用putty远程访问软件登录,但这次不需要登 ...

  4. Pandas基础教程

    pandas教程 更多地可以 参考教程 安装 pip install pandas pandas的类excel操作,超级方便: import pandas as pd dates = pd.date_ ...

  5. ActiveMQ服务器之间传输对象,项目A发送对象到项目B接收发送对象《二》

    ActiveMQ服务器之间传输对象,项目A发送对象到项目B接收发送对象<一> 上一篇文章写到对象之间传输使用线程方式 ,无法使用监听方式,最近解决了使用监听方式接收对象,本次使用配置文件方 ...

  6. POJ 1739 Tony's Tour(插头DP)

    Description A square township has been divided up into n*m(n rows and m columns) square plots (1< ...

  7. Python学习之路3 - 字符串操作&字典

    本节内容: 常用的字符串处理. 格式化输出字符串. 字符串的替换. 字符串和二进制的相互转化. 字典的操作 字符串操作 常用的字符串处理 name = 'vector' print(name.capi ...

  8. Java学习个人备忘录之数组

    数组 概念:同一种类型数据的集合,其实数组就是一个容器. 数组的好处:可以自动给数组中的元素从0开始编号,方便操作这些元素. 格式1:元素类型[] 数组名 = new 元素类型[元素个数]; 格式2: ...

  9. 第十九次ScrumMeeting会议

    第十九次Scrum Meeting 时间:2017/12/9 地点:三公寓大厅 人员:蔡帜 王子铭 游心 解小锐 王辰昱 李金奇 杨森 陈鑫 赵晓宇 照片: 目前工作进展 名字 今日 明天的工作 蔡帜 ...

  10. jsp文件中charset和pageEncoding的区别

    jsp文件中charset和pageEncoding的区别:  contentType的charset是指服务器发送给客户端时的内容编码,contentType里的charset=utf-8是指示页面 ...