MySQL 5.6 Index Condition Pushdown
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使用索引元组评估下推的索引条件。如果没有满足where条件,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优化器在执行索引区间扫描之后也不再扫描组合索引其后面的部分。
接下来我们来看看一个例子:
mysql> select version();
+-------------+
| version() |
+-------------+
| 5.5.25a-log |
+-------------+
1 row in set (0.00 sec) mysql>
mysql> show create table rental\G
*************************** 1. row ***************************
Table: rental
Create Table: CREATE TABLE `rental` (
`rental_id` int(11) NOT NULL AUTO_INCREMENT,
`rental_date` datetime NOT NULL,
`inventory_id` mediumint(8) unsigned NOT NULL,
`customer_id` smallint(5) unsigned NOT NULL,
`return_date` datetime DEFAULT NULL,
`staff_id` tinyint(3) unsigned NOT NULL,
`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`rental_id`),
UNIQUE KEY `rental_date` (`rental_date`,`inventory_id`,`customer_id`),
KEY `idx_fk_inventory_id` (`inventory_id`),
KEY `idx_fk_customer_id` (`customer_id`),
KEY `idx_fk_staff_id` (`staff_id`),
CONSTRAINT `fk_rental_customer` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`) ON UPDATE CASCADE,
CONSTRAINT `fk_rental_inventory` FOREIGN KEY (`inventory_id`) REFERENCES `inventory` (`inventory_id`) ON UPDATE CASCADE,
CONSTRAINT `fk_rental_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=16050 DEFAULT CHARSET=utf8
1 row in set (0.03 sec) mysql>
在没有使用ICP情况下的查询:
mysql> explain select * from rental where rental_date = '2006-02-14 15:16:03' and customer_id >= 300 and customer_id <= 400;
+----+-------------+--------+------+--------------------------------+-------------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+--------------------------------+-------------+---------+-------+------+-------------+
| 1 | SIMPLE | rental | ref | rental_date,idx_fk_customer_id | rental_date | 8 | const | 181 | Using where |
+----+-------------+--------+------+--------------------------------+-------------+---------+-------+------+-------------+
1 row in set (0.00 sec) mysql>
优化器首先使用复合索引rental_date的首字段rental_date过滤出符合条件rental_date='2006-02-14 15:16:03'的记录(执行计划中key字段显示rental_date),然后根据复合索引rental_date回表获取记录后,最终根据条件customer_id >= 300 and customer_id <= 400来过滤出最后的查询结果(执行计划中Extra字段显示为Using where)
下面看看开启ICP的情况(MySQL 5.6支持)
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.6.10 |
+-----------+
1 row in set (0.01 sec) mysql>
mysql> explain select * from rental where rental_date = '2006-02-14 15:16:03' and customer_id >= 300 and customer_id <= 400;
+----+-------------+--------+------+--------------------------------+-------------+---------+-------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+--------------------------------+-------------+---------+-------+------+-----------------------+
| 1 | SIMPLE | rental | ref | rental_date,idx_fk_customer_id | rental_date | 5 | const | 181 | Using index condition |
+----+-------------+--------+------+--------------------------------+-------------+---------+-------+------+-----------------------+
1 row in set (0.00 sec) mysql>
Using index condition 就表示MySQL使用了ICP来优化查询,在检索的时候把条件customer_id的过滤操作下推到存储引擎层来完成。这样能降低不必要的IO访问。
1.首先存储引擎根据条件rental_date = '2006-02-14 15:16:03'和customer_id >= 300 and customer_id <= 400来过滤索引,在索引上过滤customer_id条件
2.根据索引过滤后的记录获取数据
参考资料
http://olavsandstaa.blogspot.co.uk/2011/04/mysql-56-index-condition-pushdown.html
https://mariadb.com/kb/en/index-condition-pushdown/
MySQL 5.6 Index Condition Pushdown的更多相关文章
- 浅析MySQL中的Index Condition Pushdown (ICP 索引条件下推)和Multi-Range Read(MRR 索引多范围查找)查询优化
本文出处:http://www.cnblogs.com/wy123/p/7374078.html(保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误 ...
- MySQL 查询优化之 Index Condition Pushdown
MySQL 查询优化之 Index Condition Pushdown Index Condition Pushdown限制条件 Index Condition Pushdown工作原理 ICP的开 ...
- 【mysql】关于Index Condition Pushdown特性
ICP简介 Index Condition Pushdown (ICP) is an optimization for the case where MySQL retrieves rows from ...
- MySQL索引与Index Condition Pushdown
实际上,这个页面所讲述的是在MariaDB 5.3.3(MySQL是在5.6)开始引入的一种叫做Index Condition Pushdown(以下简称ICP)的查询优化方式.由于本身不是一个层面的 ...
- MySQL ICP(Index Condition Pushdown)特性
一.SQL的where条件提取规则 在ICP(Index Condition Pushdown,索引条件下推)特性之前,必须先搞明白根据何登成大神总结出一套放置于所有SQL语句而皆准的where查询条 ...
- MySQL索引与Index Condition Pushdown(二)
实验 先从一个简单的实验开始直观认识ICP的作用. 安装数据库 首先需要安装一个支持ICP的MariaDB或MySQL数据库.我使用的是MariaDB 5.5.34,如果是使用MySQL则需要5.6版 ...
- MySQL索引与Index Condition Pushdown(employees示例)
实验 先从一个简单的实验开始直观认识ICP的作用. 安装数据库 首先需要安装一个支持ICP的MariaDB或MySQL数据库.我使用的是MariaDB 5.5.34,如果是使用MySQL则需要5.6版 ...
- MySQL 中Index Condition Pushdown (ICP 索引条件下推)和Multi-Range Read(MRR 索引多范围查找)查询优化
一.ICP优化原理 Index Condition Pushdown (ICP),也称为索引条件下推,体现在执行计划的上是会出现Using index condition(Extra列,当然Extra ...
- MySQL 优化之 ICP (index condition pushdown:索引条件下推)
ICP技术是在MySQL5.6中引入的一种索引优化技术.它能减少在使用 二级索引 过滤where条件时的回表次数 和 减少MySQL server层和引擎层的交互次数.在索引组织表中,使用二级索引进行 ...
随机推荐
- iLBC
iLBC是一种专为包交换网络通信设计的编解码,优于目前流行的G.729.G.723.1,对丢包进行了特有处理,即使在丢包率 相当高的网络环境下,仍可获得非常清晰的语音效果.
- Linux 目录结构_004
前言 Linux文件系统层次标准,英文全称Filesystem Hierarchy Standard,英文简称FHS. 由于利用Linux来开发产品的团队和个人实在太多了,如果每个人都以自己的想法来配 ...
- OpenGL 太阳系行星拾取例子(GL_SELECT) VS2008 + glut实现
太阳系:Solar System 以太阳(Sun)为中心,由内到外分别是: 水星(Mercury) 金星(Venus) 地球(Earth) 火星(Mars) 木星(Jupiter) 土星(Saturn ...
- 使用 ssh -R 穿透局域网访问内部服务器主机,反向代理 无人值守化
一.搭建SSH方向代理 准备: 局域网主机(虚拟主机): 192.168.6.233 CentOS 6.7 阿里云服务器:120.25.68.60 CentOS 6.7 1. 阿里云服务器12 ...
- ASP.NET MVC 4 (九) 模型绑定
模型绑定指的是MVC从浏览器发送的HTTP请求中为我们创建.NET对象,在HTTP请求和C#间起着桥梁的作用.模型绑定的一个最简单的例子是带参数的控制器action方法,比如我们注册这样的路径映射: ...
- Git 学习笔记--删除错误提交的commit
如果不小心把错误的commit给commit了,可以对其进行撤销 1.使用git log查看commit日志,找到错误提交前一版本commit的哈希值; 2.使用git reset --hard co ...
- Redis JdkSerializationRedisSerializer,stringRedisSerializer,ProtoBuf 体积,性能简单比较.
/** * User: laizhenwei * Date: 2018-04-10 Time: 14:17 * Description: */ @RunWith(SpringRunner.class) ...
- 理解PEP333-WSGI
声明:这篇文章只是为了整体理解WSGI,会忽略很多细节,要详细了解请参看文后的参考资料 WSGI概述 WSGI全称是Python Web Server Gateway Interface(Python ...
- [转]CDN(内容分发网络)技术原理
1. 前言 Internet的高速发展,给人们的工作和生活带来了极大的便利,对Internet的服务品质和访问速度要求越来越高,虽然带宽不断增加, 用户数量也在不断增加,受Web服务器的负荷和传输距离 ...
- 10.24CRM完成
2018-10-24 16:16:59 已经完成了crm项目: 项目做完了,这几天可以安静整理Django啦!!!把博客整理一下! 然后再过几天针就可以回学校啦!! 今天程序员节 节日快乐!hell ...