原文地址:http://www.cnblogs.com/zengkefu/p/5684101.html

一什么是"索引条件下推"

"索引条件下推",称为 Index Condition Pushdown (ICP),这是MySQL提供的用某一个索引对一个特定的表从表中获取元组",注意我们这里特意强调了"一个",这是因为这样的索引优化不是用于多表连接而是用于单表扫描,确切地说,是单表利用索引进行扫描以获取数据的一种方式。

二 "索引条件下推"的目的

用ySQL官方手册描述:

The goal of ICP is to reduce the number of full-record reads and thereby reduce IO operations. For InnoDB clustered indexes, the complete record is already read into the InnoDB buffer. Using ICP in this case does not reduce IO.

这句官方描述,一是说明减少完整记录(一条完整元组)读取的个数;二是说明对于InnoDB聚集索引无效,只能是对SECOND INDEX这样的非聚集索引有效。

三原理

先看实例:

mysql> set optimizer_switch='index_condition_pushdown=off'; //关闭ICP
Query OK, 0 rows affected (0.00 sec)
mysql> EXPLAIN SELECT * FROM t4 WHERE 1=t4.a4 AND t4.name like 'char%';
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | t4    | NULL       | range | a4_i          | a4_i | 28      | NULL |    1 |   100.00 | Using where |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> set optimizer_switch='index_condition_pushdown=on';  //打开ICP,则Extra列中显示"Using index condition"
Query OK, 0 rows affected (0.00 sec)
mysql> EXPLAIN SELECT * FROM t4 WHERE 1=t4.a4 AND t4.name like 'char%';
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | t4    | NULL       | range | a4_i          | a4_i | 28      | NULL |    1 |   100.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
如果打开ICP,则执行计划的Extra列会显示"Using index condition",这表明在。
借用网上的2张图加以改造,并配以解释,来说明原理,更清晰地说明问题。
图一:不使用ICP技术(过程使用数字符号标示,如①②③等)

过程解释:
①:MySQL Server发出读取数据的命令,这是在执行器中执行如下代码段,通过函数指针和handle接口调用存储引擎的索引读或全表表读。此处进行的是索引读。
    if (in_first_read)
    {
      in_first_read= false;
      error= (*qep_tab->read_first_record)(qep_tab); //设定合适的读取函数,如设定索引读函数/全表扫描函数
    }
    else
      error= info->read_record(info);
②、③:进入存储引擎,读取索引树,在索引树上查找,把满足条件的(经过查找,红色的满足)从表记录中读出(步骤④,通常有IO),从存储引擎返回⑤标识的结果。此处,不仅要在索引行进行索引读取(通常是内存中,速度快。步骤③),还要进行进行步骤④,通常有IO。
⑥:从存储引擎返回查找到的多条元组给MySQL Server,MySQL Server在⑦得到较多的元组。
⑦--⑧:⑦到⑧依据WHERE子句条件进行过滤,得到满足条件的元组。注意在MySQL Server层得到较多元组,然后才过滤,最终得到的是少量的、符合条件的元组。
图二:使用ICP技术(过程使用数字符号标示,如①②③等)

过程解释:

①:MySQL Server发出读取数据的命令,过程同图一。

②、③:进入存储引擎,读取索引树,在索引树上查找,把满足已经下推的条件的(经过查找,红色的满足)从表记录中读出(步骤④,通常有IO),从存储引擎返回⑤标识的结果。此处,不仅要在索引行进行索引读取(通常是内存中,速度快。步骤③),还要在③这个阶段依据下推的条件进行进行判断,不满足条件的,不去读取表中的数据,直接在索引树上进行下一个索引项的判断,直到有满足条件的,才进行步骤④,这样,较没有ICP的方式,IO量减少。

⑥:从存储引擎返回查找到的少量元组给MySQL Server,MySQL Server在⑦得到少量的元组。因此比较图一无ICP的方式,返回给MySQL Server层的即是少量的、符合条件的元组。
 另外,图中的部件层次关系,不再进行解释。
四 实现细节
1 ICP只能用于辅助索引,不能用于聚集索引。
2 ICP只用于单表,不是多表连接是的连接条件部分(如开篇强调)
如果表访问的类型为:
3 EQ_REF/REF_OR_NULL/REF/SYSTEM/CONST: 可以使用ICP
4 range:如果不是"index tree only(只读索引)",则有机会使用ICP
5 ALL/FT/INDEX_MERGE/INDEX_SCAN:  不可以使用ICP

五上楼

1 条件下推,一直是SQL优化的基本规则。所以,条件下推技术是常规技术。数据库的优化器几乎不会不实现条件下推优化。

2 技术层面,MySQL存在MySQL Server层和储存层,使得条件下推显得"有些割裂"。

3 非技术层面,MySQL之所以引入ICP,猜一猜或拍拍脑袋,原因你懂得。

六从代码的角度看

对于图一的解释,给出了读数据的代码片段,无论是关闭还是打开ICP, 从下面给出的函数调用关系可以看出,2幅图对应的情况下,代码路径是一致的.

首条元组读取调用关系(蓝色标识和非首条元组不同之处):

JOIN::exec()->do_select()->sub_select()->join_init_read_record()->rr_quick()->
  QUICK_RANGE_SELECT::get_next()->ha_innobase::multi_range_read_next()->
  DsMrr_impl::dsmrr_next()->handler::multi_range_read_next()->
  handler::read_range_first()->handler::ha_index_read_map()->
  handler::index_read_map()->ha_innobase::index_read()

除首条元组读取调用关系(蓝色标识和首条元组不同之处)

JOIN::exec()->do_select()->sub_select()->join_init_read_record()->rr_quick()->
  QUICK_RANGE_SELECT::get_next()->ha_innobase::multi_range_read_next()->
  DsMrr_impl::dsmrr_next()->handler::multi_range_read_next()->
  handler::read_range_next()->handler::ha_index_next()->
  ha_innobase::index_next()->ha_innobase::general_fetch()

ps:我的理解:如有一个复合索引a,b。此时对a = 10 and b>20 这种情况 type肯定是ref,根据a=10交给存储引擎执行索引搜索,将a=10的结果交给mysql sercie层之后,它在根据where进行过滤,也就是b > 20的过滤。但是有了索引条件下推,它就会把a = 10 and b>20两个条件一起交给存储引擎层,虽然还是按照a=10来搜索数据,不过在存储引擎层的时候,可以判断不符合b > 20的数据,直接丢弃。

mysql5.6新功能索引条件下推(转载)的更多相关文章

  1. MySQL5.6之Index Condition Pushdown(ICP,索引条件下推)-Using index condition

    http://blog.itpub.net/22664653/viewspace-1210844/ -- 这篇博客写的更细,以后看 ICP(index condition pushdown)是mysq ...

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

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

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

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

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

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

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

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

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

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

  7. MySQL5.6新特性Index conditontion pushdow

    index condition pushdown是MySQL5.6的新特性,主要是对MySQL索引使用的优化. Index condition push简称ICP,索引条件下推,将索引条件从serve ...

  8. MySQL--索引条件下推优化

    http://blog.163.com/li_hx/blog/static/1839914132015782821512/ 一 什么是“索引条件下推” “索引条件下推”,称为 Index Condit ...

  9. [转载]新功能:用微软的Live Writer离线写博文

    原文地址:Writer离线写博文">新功能:用微软的Live Writer离线写博文作者:新浪博客 Writer离线写博文" title="[转载]新功能:用微软的 ...

随机推荐

  1. Leetcode之动态规划(DP)专题-1025. 除数博弈(Divisor Game)

    Leetcode之动态规划(DP)专题-1025. 除数博弈(Divisor Game) 爱丽丝和鲍勃一起玩游戏,他们轮流行动.爱丽丝先手开局. 最初,黑板上有一个数字 N .在每个玩家的回合,玩家需 ...

  2. 华为HCNA乱学Round 9:VRRP

  3. 【VS开发】设备控制台 (DevCon.exe) 示例

    设备控制台 (DevCon.exe) 示例 本部分提供以下设备控制台 (DevCon.exe) 命令的示例: DevCon HwIDs 示例 1:查找所有硬件 ID 示例 2:使用模式查找硬件 ID ...

  4. Elasticsearch-如何识别一篇文档

    ES-识别文档 为了识别同一个索引中的某篇文档,ES使用_uid中的文档类型和ID结合体._uid字段是由_id和_type字段组成,当搜索或者检索文档的时候总是能获得这两项信息. FengZhend ...

  5. luoguP1379-八数码难题(双向bfs)

    题目链接:https://www.luogu.org/problemnew/show/P1379 题意:用字符串表示八数码,求根据给定八数码得到末状态“123804765”最少的步数. 思路:这题很方 ...

  6. luoguP1045 (Java大数)

    题目链接:https://www.luogu.org/problemnew/show/P1045 题意:给定p(1000<p<3100000),求2^p-1的位数和最后500位(若不足高位 ...

  7. ThreadPoolExecutor的重要参数

    一.ThreadPoolExecutor的重要参数 1.corePoolSize:核心线程数         * 核心线程会一直存活,及时没有任务需要执行         * 当线程数小于核心线程数时 ...

  8. ABC134F Permutation Oddness

    Problem Statement Let us define the oddness of a permutation $p = \{p_1, p_2, \dots, p_n\}$ of $\{1, ...

  9. Git上传相关资料

    ############ssh key及 配置信息############# 设置Git的user name和email: $ git config --global user.name " ...

  10. Laravel5.5 实现session配置

    \Illuminate\Session\Middleware\StartSession::class,\Illuminate\View\Middleware\ShareErrorsFromSessio ...