【mysql】关于Index Condition Pushdown特性
ICP简介
Index Condition Pushdown (ICP) is an optimization for the case where MySQL retrieves rows from a table using an index. Without ICP, the storage engine traverses the index to locate rows in the base table and returns them to the MySQL server which evaluates the WHEREcondition for the rows. With ICP enabled, and if parts of the WHERE condition can be evaluated by using only fields from the index, the MySQL server pushes this part of the WHERE condition down to the storage engine. The storage engine then evaluates the pushed index condition by using the index entry and only if this is satisfied is the row read from the table. ICP can reduce the number of times the storage engine must access the base table and the number of times the MySQL server must access the storage engine.
也就说:利用索引(二级索引)来过滤一部分where条件
测试
导入数据库
wget https://launchpad.net/test-db/employees-db-1/1.0.6/+download/employees_db-full-1.0.6.tar.bz2
tar jxf employees_db-full-1.0.6.tar.bz2
cd employees_db
mysql -uroot -p < employees.sql
表结构
mysql> show create table employees \G
*************************** 1. row ***************************
Table: employees
Create Table: CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` enum('M','F') NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`),
KEY `index_bh` (`birth_date`,`hire_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
一些表数据
mysql> select @@optimizer_switch like '%index_condition_pushdown%' \G
*************************** 1. row ***************************
@@optimizer_switch like '%index_condition_pushdown%': 1
1 row in set (0.00 sec) mysql> select @@optimizer_switch like '%index_condition_pushdown%' \G
*************************** 1. row ***************************
@@optimizer_switch like '%index_condition_pushdown%': 1
1 row in set (0.00 sec) mysql> select @@query_cache_type;
+--------------------+
| @@query_cache_type |
+--------------------+
| OFF |
+--------------------+
1 row in set (0.01 sec) mysql> select count(*) from employees;
+----------+
| count(*) |
+----------+
| 300024 |
+----------+
1 row in set (0.17 sec) mysql> set profiling=1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
建立索引
alter table employees add index index_bh (`birth_date`,`hire_date`);
查询分析
mysql> explain select * from employees where birth_date between '1955-01-01' and '1955-12-31' and datediff(hire_date,birth_date)>12300 and first_name like 'S%b%';
+----+-------------+-----------+-------+---------------+----------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------+---------------+----------+---------+------+-------+-------------+
| 1 | SIMPLE | employees | range | index_bh | index_bh | 3 | NULL | 46318 | Using where |
+----+-------------+-----------+-------+---------------+----------+---------+------+-------+-------------+
1 row in set (0.00 sec) mysql> SET optimizer_switch='index_condition_pushdown=on';
Query OK, 0 rows affected (0.00 sec) mysql> explain select * from employees where birth_date between '1955-01-01' and '1955-12-31' and datediff(hire_date,birth_date)>12300 and first_name like 'S%b%';
+----+-------------+-----------+-------+---------------+----------+---------+------+-------+------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+-------+---------------+----------+---------+------+-------+------------------------------------+
| 1 | SIMPLE | employees | range | index_bh | index_bh | 3 | NULL | 46318 | Using index condition; Using where |
+----+-------------+-----------+-------+---------------+----------+---------+------+-------+------------------------------------+
1 row in set (0.01 sec)
执行查询
mysql> show profiles; +----------+------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
| 1 | 0.00278025 | desc employees |
| 2 | 0.00049775 | show create table employees |
| 3 | 0.07444550 | select * from employees where birth_date between '1955-01-01' and '1955-12-31' and datediff(hire_date,birth_date)>12300 and first_name like 'S%b%' |
| 4 | 0.00027500 | SET optimizer_switch='index_condition_pushdown=off' |
| 5 | 0.12347025 | select * from employees where birth_date between '1955-01-01' and '1955-12-31' and datediff(hire_date,birth_date)>12300 and first_name like 'S%b%' |
+----------+------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
从结果可以看出来开启ICP之后确实快不少
启用ICP之后,可以用索引来筛选 datediff(hire_date,birth_date)>12300 记录,不需要读出整条记录
ICP原理
如下图所示(图来自MariaDB)
1、优化器没有使用ICP时
- 在存储引擎层,首先读取索引元组(index tuple),然后使用(index tuple)在基表中(base table)定位和读取整行数据
- 到服务器层,匹配where条件,如果该行数据满足where条件则使用,否则丢弃
- 指针向下一行移动,重复以上过程

2、使用ICP的时候
- 如果where条件的一部分能够通过使用索引中的字段进行过滤,那么服务器层将把这部分where条件Pushdown到存储引擎层
- 到存储引擎层,从索引中读取索引元组(index tuple),使用索引元组进行判断,如果没有满足where条件,则处理下一条索引元组(index tuple),只有当索引元组满足条件的时候,才会去基表中读取数据

ICP的使用条件
1、只能用于二级索引(secondary index)
2、explain显示的执行计划中type值(join 类型)为range、 ref、 eq_ref或者ref_or_null。且查询需要访问表的整行数据,即不能直接通过二级索引的元组数据获得查询结果(索引覆盖)
3、ICP可以用于MyISAM和InnnoDB存储引擎,不支持分区表(5.7将会解决这个问题)
4、ICP的加速效果取决于在存储引擎内通过ICP筛选掉的数据的比例
参考文章
https://mariadb.com/kb/en/index-condition-pushdown/
http://dev.mysql.com/doc/refman/5.6/en/index-condition-pushdown-optimization.html
http://blog.codinglabs.org/articles/index-condition-pushdown.html
【mysql】关于Index Condition Pushdown特性的更多相关文章
- MySQL 中Index Condition Pushdown (ICP 索引条件下推)和Multi-Range Read(MRR 索引多范围查找)查询优化
一.ICP优化原理 Index Condition Pushdown (ICP),也称为索引条件下推,体现在执行计划的上是会出现Using index condition(Extra列,当然Extra ...
- MySQL 之 Index Condition Pushdown(ICP)
简介 Index Condition Pushdown (ICP)是MySQL 5.6 版本中的新特性,是一种在存储引擎层使用索引过滤数据的一种优化方式. 当关闭ICP时,index 仅仅是data ...
- MySQL中Index Condition Pushdown(ICP)优化
在MySQL 5.6开始支持的一种根据索引进行查询的优化方式.之前的MySQL数据库版本不支持ICP,当进行索引查询是,首先根据索引来查找记录,然后在根据WHERE条件来过滤记录.在支持ICP后,My ...
- MySQL 5.6新特性 -- Index Condition Pushdown
Index Condition Pushdown(ICP)是针对mysql使用索引从表中检索行数据时的一种优化方法. 在没有ICP特性之前,存储引擎根据索引去基表查找并将数据返回给mysql se ...
- MySQL ICP(Index Condition Pushdown)特性
一.SQL的where条件提取规则 在ICP(Index Condition Pushdown,索引条件下推)特性之前,必须先搞明白根据何登成大神总结出一套放置于所有SQL语句而皆准的where查询条 ...
- 1229【MySQL】性能优化之 Index Condition Pushdown
转自http://blog.itpub.net/22664653/viewspace-1210844/ [MySQL]性能优化之 Index Condition Pushdown2014-07-06 ...
- 浅析MySQL中的Index Condition Pushdown (ICP 索引条件下推)和Multi-Range Read(MRR 索引多范围查找)查询优化
本文出处:http://www.cnblogs.com/wy123/p/7374078.html(保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误 ...
- MySQL Index Condition Pushdown
Index Condition Pushdown (ICP)是MySQL 5.6 版本中的新特性,是一种在存储引擎层使用索引过滤数据的一种优化方式.[Index Condition Pushdown] ...
- MySQL Index Condition Pushdown 原理与解析
Index Condition Pushdown(ICP)是针对mysql使用索引从表中检索行数据时的一种优化方法. 原理: 在没有ICP特性之前,存储引擎根据索引去基表查找并将数据返回给mysq ...
随机推荐
- Angular系列----AngularJS入门教程04:迭代器过滤(转载)
我们在上一步做了很多基础性的训练,所以现在我们可以来做一些简单的事情喽.我们要加入全文检索功能(没错,这个真的非常简单!).同时,我们也会写一个端到端测试,因为一个好的端到端测试可以帮上很大忙.它监视 ...
- springMVC源码分析之拦截器
一个东西用久了,自然就会从仅使用的层面上升到探究其原理的层面,在javaweb中springmvc更是如此,越是优秀的框架,其底层实现代码更是复杂,而在我看来,一个优秀程序猿就相当于一名武林高手,不断 ...
- BZOJ1003 物流运输 最短路+DP
1003: [ZJOI2006]物流运输 Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条 ...
- [Solution] Microsoft Windows 服务(3) 使用Quartz.net定时任务
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,Quartz.net 就是Quartz的移植版本.Quartz可以用来创建简单或为运行十个,百个,甚至是 ...
- 三分套三分 --- HDU 3400 Line belt
Line belt Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=3400 Mean: 给出两条平行的线段AB, CD,然后一 ...
- C#设计模式——桥接模式(Bridge Pattern)
一.概述在软件开发中,我们有时候会遇上一个对象具有多个变化维度.比如对汽车对象来说,可能存在不同的汽车类型,如公共汽车.轿车等,也可能存在不同的发动机,如汽油发动机.柴油发动机等.对这类对象,可应用桥 ...
- Winform开发框架之附件管理应用
在很多常规的管理系统里面,都可能有附件管理的需求,在我做的一系列医疗行业的病人信息管理系统里面,都希望能很好的管理病人的相关资料,分门别类的进行存储,需要的时候可以预览查看,那么这个功能我们可以把它独 ...
- SVN 忽略文件但不删除文件
SVN忽略一些不必要的文件但不删除 如果svn仓库中有一些不希望被别人提交的文件 该如何忽略掉对这个文件的更改但又不删除这个文件呢? 在找了一堆解决方案后得出了如下结论 去除要被忽略文件的版本控制 基 ...
- IE Unknown runtime error
1. 在函数中使用原生的js的时候,有时在IE下会出现Unknown runtime error 火狐下正常 2. 解决办法, 将原生js改成jquery处理兼容问题 document.getElem ...
- Mysql denied for user 'odbc@localhost' || denied for user 'root@localhost'
1. Question Description: 1.1 mysql version: mysql-5.7.11-win64.zip 1.2 if you connect to the mys ...