Index Condition Pushdown(ICP)是针对mysql使用索引从表中检索行数据时的一种优化方法。
 
在没有ICP特性之前,存储引擎根据索引去基表查找并将数据返回给mysql server,mysql server再根据where条件进行数据过滤。
有了ICP之后,在取出索引的同时,判断是否可以根据索引中的列进行where条件过滤,也就是将where的部分过滤操作放在了存储引擎层。这样就会减少上层sql层对记录的获取。
 
ICP优化支持range、ref、eq_ref、ref_or_null类型的查询。查询优化器会给出相应的提示:Using index condition。当开启ICP后,在执行计划的extra列会显示:Using index condition。
 
ICP支持innodb、myisam表。对于innodb表,ICP只是用于辅助索引。
 
在5.6中,ICP不支持分区表。这个问题在mysql 5.7中得到解决。
 
优化器使用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之前:
 
开启ICP之后,就变成:
默认是开启ICP的,手动开启/关闭ICP: 
set optimizer_switch = 'index_condition_pushdown=off';
set optimizer_switch = 'index_condition_pushdown=on';

  

 测试过程

1.环境准备

#mysql 5.6.25
#关闭结果缓存
mysql> set global query_cache_size=0;
mysql> set query_cache_type=off; #查看表结构
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 `idx_first_last_name` (`first_name`,`last_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec) mysql>

2.开启ICP后进行测试

mysql> set profiling = 1;
mysql> select * from employees where first_name='Anneke' and last_name like '%sig' ;
mysql> explain select * from employees where first_name='Anneke' and last_name like '%sig' ;
mysql> show profiles;
mysql> show profile cpu,block io for query 1;

3.关闭ICP后进行测试

mysql> set optimizer_switch='index_condition_pushdown=off';
mysql> set profiling = 1;
mysql> select * from employees where first_name='Anneke' and last_name like '%sig' ;
mysql> explain select * from employees where first_name='Anneke' and last_name like '%sig' ;
mysql> show profiles;
mysql> show profile cpu,block io for query 1;

4.结果比较

开启ICP后的执行计划:执行计划中extra部分的内容是"using index condition"

mysql> explain select * from employees where first_name='Anneke' and last_name like '%sig' ;
+----+-------------+-----------+------+---------------------+---------------------+---------+-------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------------+---------------------+---------+-------+------+-----------------------+
| 1 | SIMPLE | employees | ref | idx_first_last_name | idx_first_last_name | 44 | const | 224 | Using index condition |
+----+-------------+-----------+------+---------------------+---------------------+---------+-------+------+-----------------------+

关闭ICP后的执行计划:执行计划中extra部分的内容是"using where"

mysql> explain select * from employees where first_name='Anneke' and last_name like '%sig' ;
+----+-------------+-----------+------+---------------------+---------------------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------------+---------------------+---------+-------+------+-------------+
| 1 | SIMPLE | employees | ref | idx_first_last_name | idx_first_last_name | 44 | const | 224 | Using where |
+----+-------------+-----------+------+---------------------+---------------------+---------+-------+------+-------------+

 

开启ICP后的profile内容:Sending data部分的值是0.000212s

mysql> show profile cpu,block io for query 1;
+----------------------+----------+----------+------------+--------------+---------------+
| Status | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out |
+----------------------+----------+----------+------------+--------------+---------------+
| starting | 0.000114 | 0.000000 | 0.000000 | 0 | 0 |
| checking permissions | 0.000007 | 0.000000 | 0.000000 | 0 | 0 |
| Opening tables | 0.000018 | 0.000000 | 0.000000 | 0 | 0 |
| init | 0.000034 | 0.000000 | 0.000000 | 0 | 0 |
| System lock | 0.000008 | 0.000000 | 0.000000 | 0 | 0 |
| optimizing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 |
| statistics | 0.000383 | 0.000000 | 0.000000 | 0 | 0 |
| preparing | 0.000019 | 0.000000 | 0.000000 | 0 | 0 |
| executing | 0.000002 | 0.000000 | 0.000000 | 0 | 0 |
| Sending data | 0.000212 | 0.000000 | 0.000000 | 0 | 0 |
| end | 0.000004 | 0.000000 | 0.000000 | 0 | 0 |
| query end | 0.000004 | 0.000000 | 0.000000 | 0 | 0 |
| closing tables | 0.000006 | 0.000000 | 0.000000 | 0 | 0 |
| freeing items | 0.000020 | 0.000000 | 0.000000 | 0 | 0 |
| cleaning up | 0.000011 | 0.000000 | 0.000000 | 0 | 0 |
+----------------------+----------+----------+------------+--------------+---------------+

关闭ICP后的profile内容:Sending data部分的值是0.010990s

mysql> show profile cpu,block io for query 1;
+----------------------+----------+----------+------------+--------------+---------------+
| Status | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out |
+----------------------+----------+----------+------------+--------------+---------------+
| starting | 0.000165 | 0.000000 | 0.000000 | 0 | 0 |
| checking permissions | 0.000022 | 0.000000 | 0.000000 | 0 | 0 |
| Opening tables | 0.000027 | 0.000000 | 0.000000 | 0 | 0 |
| init | 0.000039 | 0.000000 | 0.000000 | 0 | 0 |
| System lock | 0.000008 | 0.000000 | 0.000000 | 0 | 0 |
| optimizing | 0.000037 | 0.001000 | 0.000000 | 0 | 0 |
| statistics | 0.000483 | 0.001000 | 0.000000 | 0 | 0 |
| preparing | 0.000022 | 0.000000 | 0.000000 | 0 | 0 |
| executing | 0.000002 | 0.000000 | 0.000000 | 0 | 0 |
| Sending data | 0.010990 | 0.007999 | 0.002000 | 0 | 0 |
| end | 0.000009 | 0.000000 | 0.000000 | 0 | 0 |
| query end | 0.000005 | 0.000000 | 0.000000 | 0 | 0 |
| closing tables | 0.000008 | 0.000000 | 0.000000 | 0 | 0 |
| freeing items | 0.000028 | 0.000000 | 0.000000 | 0 | 0 |
| cleaning up | 0.000014 | 0.000000 | 0.000000 | 0 | 0 |
+----------------------+----------+----------+------------+--------------+---------------+

  

其它:

当sql使用覆盖索引时,不支持ICP优化方法

mysql> explain select first_name,last_name from employees where first_name='Anneke' and last_name='Porenta' ;
+----+-------------+-----------+------+---------------------+---------------------+---------+-------------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------------+---------------------+---------+-------------+------+--------------------------+
| 1 | SIMPLE | employees | ref | idx_first_last_name | idx_first_last_name | 94 | const,const | 1 | Using where; Using index |
+----+-------------+-----------+------+---------------------+---------------------+---------+-------------+------+--------------------------+
mysql> explain select * from employees where first_name='Anneke' and last_name='Porenta' ;
+----+-------------+-----------+------+---------------------+---------------------+---------+-------------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------------+---------------------+---------+-------------+------+-----------------------+
| 1 | SIMPLE | employees | ref | idx_first_last_name | idx_first_last_name | 94 | const,const | 1 | Using index condition |
+----+-------------+-----------+------+---------------------+---------------------+---------+-------------+------+-----------------------+

  

MySQL 5.6新特性 -- Index Condition Pushdown的更多相关文章

  1. 1229【MySQL】性能优化之 Index Condition Pushdown

    转自http://blog.itpub.net/22664653/viewspace-1210844/  [MySQL]性能优化之 Index Condition Pushdown2014-07-06 ...

  2. 【MySQL】性能优化之 Index Condition Pushdown

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

  3. [MySQL] 联合索引与using index condition

    1.测试联合索引的最左原则的时候, 发现了5.6版本后的新特性Index Condition Pushdown 2.含义就是存储引擎层根据索引尽可能的过滤数据,然后在返回给服务器层根据where其他条 ...

  4. MySQL ICP(Index Condition Pushdown)特性

    一.SQL的where条件提取规则 在ICP(Index Condition Pushdown,索引条件下推)特性之前,必须先搞明白根据何登成大神总结出一套放置于所有SQL语句而皆准的where查询条 ...

  5. 【mysql】关于Index Condition Pushdown特性

    ICP简介 Index Condition Pushdown (ICP) is an optimization for the case where MySQL retrieves rows from ...

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

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

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

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

  8. MySQL 之 Index Condition Pushdown(ICP)

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

  9. MySQL Index Condition Pushdown

    Index Condition Pushdown (ICP)是MySQL 5.6 版本中的新特性,是一种在存储引擎层使用索引过滤数据的一种优化方式.[Index Condition Pushdown] ...

随机推荐

  1. hdu 5381

    题解: 还是比较水的一道题 首先可以发现每个数最多被除log次,所以有连续一段相同 然后我想的是变成矩形统计前缀和问题用主席树来维护 然后发现这题很卡空间 qwq acm依旧很多64mb的题 首先比较 ...

  2. [转]Mysql 存储过程和函数区别

    http://blog.csdn.net/wangsifu2009/article/details/6725213 存储过程是用户定义的一系列sql语句的集合,涉及特定表或其它对象的任务,用户可以调用 ...

  3. 【Java】 剑指offer(52) 两个链表的第一个公共结点

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入两个链表,找出它们的第一个公共结点. 思路 蛮力法:遍历第一个 ...

  4. Chameleon

    # -*- coding: utf-8 -*- """ Created on Tue Dec 18 09:55:16 2018 @author: Mark,LI &quo ...

  5. Python学习——Python线程

    一.线程创建 #方法一:将要执行的方法作为参数传给Thread的构造方法 import threading import time def show(arg): time.sleep(2) print ...

  6. Session失效后所有Ajax请求跳转登录地址

    当登录的Session失效后,采用ajax请求数据时会没有反应,这时候应该自动跳转到登录页面,让用户重新登录. 全局配置以下可实现 $(function() { $.ajaxSetup({ compl ...

  7. u3d 地形 U3d terrain

    u3d 地形 U3d terrain 作者:韩梦飞沙 Author:han_meng_fei_sha 邮箱:313134555@qq.com E-mail: 313134555 @qq.com fbx ...

  8. 二分图带权匹配 KM算法与费用流模型建立

    [二分图带权匹配与最佳匹配] 什么是二分图的带权匹配?二分图的带权匹配就是求出一个匹配集合,使得集合中边的权值之和最大或最小.而二分图的最佳匹配则一定为完备匹配,在此基础上,才要求匹配的边权值之和最大 ...

  9. VC6配置CXimage库

    VC6下配置CxImage库教程 第一步 下载CxImage http://sourceforge.net/projects/cximage/下载相应的CxImage文件 本例使用的最新版本(7.02 ...

  10. 关于Random.Range 范围界定

    1. 当Range的参数是float时 Random.Range 范围 static function Range (min : float, max : float) : float :返回一个随机 ...