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. 百度未授权使用地图API

    百度地图管理员的回复:这是KEY服务升级的问题, 给您造成的不便,非常抱歉.但我们昨日已修复,你可以再审核一番.若不可以,请提供一下您的系统ak,邮箱或qq发送至(wangwenhai@baidu.c ...

  2. BZOJ1192 [HNOI2006]鬼谷子的钱袋 数学推理

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1192 题意概括 把一个数m拆成很多数字. 问至少拆成多少个数字,1~m中的所有数字才可以用这些数字 ...

  3. 【Java】 剑指offer(17) 在O(1)时间删除链表结点

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除 ...

  4. CSS3 根据屏幕大小显示内容(@media)

    @media (min-width: 993px) {  .footer .addZ1{display:none;}  .footer .addZ2{display:none;}  .footer . ...

  5. Manjaro 初始配置----anaconda-pycharm-opencv-tensorflow

    1.安装蟒蛇 1)安装 yaourt anaconda source /opt/anaconda/bin/active root 2)添加环境变量 在〜/ .bashrc中添加 export PATH ...

  6. SQL server学习(五)T-SQL编程之存储过程

    周五了,祝大家周末愉快. 之前一直在写SQL server的分享,今天再来个T-SQL编程中的存储过程. 存储过程 存储过程(procedure)类似于C语言中的函数,用来执行管理任务或应用复杂的业务 ...

  7. 算法进阶面试题05——树形dp解决步骤、返回最大搜索二叉子树的大小、二叉树最远两节点的距离、晚会最大活跃度、手撕缓存结构LRU

    接着第四课的内容,加入部分第五课的内容,主要介绍树形dp和LRU 第一题: 给定一棵二叉树的头节点head,请返回最大搜索二叉子树的大小 二叉树的套路 统一处理逻辑:假设以每个节点为头的这棵树,他的最 ...

  8. Python:安装MYSQL Connector

    在Python中安装MySQL Connector有如下三种方法: 1.直接安装客户端[建议使用] pip install mysqlclient 2.安装mysql连接器 pip install - ...

  9. 公开课 之 tony 电子时钟 (课堂笔记)

    # tony 之电子时钟from PyQt5.QtWidgets import QApplication, QWidget, QLCDNumber, QDesktopWidget, QVBoxLayo ...

  10. stm32与HC-SR04超声波传感器测距

    首先,先来看一下这个模块的基本功能和原理. HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm:模块包括超声波发射器.接收器与控制电路.像智能小车的测距 ...