MySQL Index Condition Pushdown(ICP)优化

Index Condition Pushdown(ICP)索引条件下推优化适用于mysql在table中通过index检索数据行,没有ICP,存储引擎层遍历索引来定位基表(base table)上的数据行并且把它们返回给server层,由server层来计算过滤where语句.使用ICP,并且where语句的部分筛选条件可以通过index来检测,则mysql server层会讲部分where 条件下推给存储引擎层。存储引擎通过使用index条目来评估下推的index condition,并且仅仅读取满足index condition的数据行。ICP可以减少存储引擎access 基表和Server层access  storage engine的次数;(图引用网友

Index Condition Pushdown 优化用作range,ref,eq_ref和ref_or_null 访问方法access表的所有行时。这策略可以用作Innodb和MyISAM表(注意5.6版本Index Condition pushdown不支持分区表,5.7支持)对于Innodb表,ICP只能用于二级索引,ICP的目标是减少基表access次数,从而减少磁盘IO操作。对于INNoDB clustered 索引,所有记录已经被读进Innodb buffer,这种情况下用ICP不能减少IO次数。

                    

  为了了解优化器如何工作,考虑当ICP没被使用时,Index扫描是怎么经行的?

1:server层为了得到下一个数据行,存储引擎读取该数据行对应的Index 条目(元组),通过该Index条目来定位返回完整的数据行(基表);

2: server层用while 语句条件来检测返回数据行,数据行的accept 或者 reject 基于检测结果。

当ICP使用时,index扫描过程:(不仅用index 来定位数据行,而且用where condition中包含的index columns来过滤数据,打个比方,根据mysql index最左前缀原则,where ‘xxx‘ = ‘hello‘ and ‘yyy‘ = ‘% xxx%‘,存储引擎只会用 ‘xxx‘列来定位数据,而‘yyy’是模糊匹配,不会使用,用不用ICP,两种情况扫描index是一样,不过用ICP,会额外使用‘%yyy%‘匹配对联合索引‘yyy’,仅读取和返回满足‘hello‘和‘%xxx%’的完整数据行,而不用Icp,读取和返回的是单独满足‘hello‘列值的数据行,)

1: 存储引擎获得对应的Index条目(非基表的数据行)。

2:用where condition中的包含的index columns 来检测对应的Index columns,如果condition不满足,处理下一条index 条目。

3: 如果condition成立,用对应的index 条目来定位返回基表完整的数据行。

4: 用where condition剩余的部分来检测storage engine返回的数据行。

当ICP 使用时,explain extra列显示 Using index condition.

 未使用ICP:

                 

 使用ICP:

                  

   在ICP优化开启时,在存储引擎端首先用索引过滤可以过滤的where条件(where中的条件列包含index列),然后再用索引做data access,被index condition过滤掉的数据不必读取,也不会返回server端,如果where条件列中有不包含在索引列中的列,则根据storage engine ICP返回的数据行再做where判断(where去除index columns的列),所以上图这种情况下server 层应该在加上Using where小块,同上上图; 见例子:

 use empolyees
mysql> desc employees.employees;
+------------+---------------+------+-----+---------+-------+
| Field      | Type          | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+-------+
| emp_no     | int(11)       | NO   | PRI | NULL    |       |
| birth_date | date          | NO   |     | NULL    |       |
| first_name | varchar(14)   | NO   |     | NULL    |       |
| last_name  | varchar(16)   | NO   |     | NULL    |       |
| gender     | enum(‘M‘,‘F‘) | NO   |     | NULL    |       |
| hire_date  | date          | NO   |     | NULL    |       |
+------------+---------------+------+-----+---------+-------+
6 rows in set (0.09 sec)
mysql> alter table employees add index idx_fn_ln (first_name,last_name );//添加联合索引
Query OK, 0 rows affected (3.98 sec)
Records: 0  Duplicates: 0  Warnings: 0

Index Condition Pushdown打开的情况下

mysql> explain select * from employees where first_name =‘Mary‘ and last_name like ‘%man‘;
+----+-------------+-----------+------+---------------+-----------+---------+-------+------+-----------------------+
| id | select_type | table     | type | possible_keys | key       | key_len | ref   | rows | Extra                 |
+----+-------------+-----------+------+---------------+-----------+---------+-------+------+-----------------------+
|  1 | SIMPLE      | employees | ref  | idx_fn_ln     | idx_fn_ln | 16      | const |  224 | Using index condition |
+----+-------------+-----------+------+---------------+-----------+---------+-------+------+-----------------------+
1 row in set (0.00 sec)

关闭的情况下:

mysql> set optimizer_switch = ‘index_condition_pushdown=off‘; //关闭index condition pushdown
Query OK, 0 rows affected (0.02 sec)

mysql> explain select * from employees where first_name =‘Mary‘ and last_name like ‘%man‘;
+----+-------------+-----------+------+---------------+-----------+---------+-------+------+-------------+
| id | select_type | table     | type | possible_keys | key       | key_len | ref   | rows | Extra       |
+----+-------------+-----------+------+---------------+-----------+---------+-------+------+-------------+
|  1 | SIMPLE      | employees | ref  | idx_fn_ln     | idx_fn_ln | 16      | const |  224 | Using where |
+----+-------------+-----------+------+---------------+-----------+---------+-------+------+-------------+
1 row in set (0.00 sec)

看where语句中包含上述联合索引,并且包含一个非索引列:

mysql> set optimizer_switch=‘index_condition_pushdown=on‘;
Query OK, 0 rows affected (0.00 sec)

mysql> explain select * from employees where first_name =‘Mary‘ and last_name =‘%man‘ and gender =‘M‘;
+----+-------------+-----------+------+---------------+-----------+---------+-------------+------+------------------------------------+
| id | select_type | table     | type | possible_keys | key       | key_len | ref         | rows | Extra                              |
+----+-------------+-----------+------+---------------+-----------+---------+-------------+------+------------------------------------+
|  1 | SIMPLE      | employees | ref  | idx_fn_ln     | idx_fn_ln | 34      | const,const |    1 | Using index condition; Using where |
+----+-------------+-----------+------+---------------+-----------+---------+-------------+------+------------------------------------+
1 row in set (0.01 sec)

同样有using index condition,不过index过滤后,Server还要根据gender列来判断一下 storage engine返回的值;

ICP只能用于二级索引,不能用于主索引。

也不是全部where条件都可以用ICP筛选,如果某where条件的字段不在索引中,当然还是要读取整条记录做筛选,在这种情况下,仍然要到server端做where筛选。

ICP的加速效果取决于在存储引擎内通过ICP筛选掉的数据的比例。

本文使用employees数据库表和数据在这里************下载,该库功能数据齐全,employees_db-full-1.0.6.tar.bz2

时间: 2024-10-24 12:11:57

MySQL Index Condition Pushdown(ICP)优化的相关文章

MySQL中Index Condition Pushdown(ICP)优化

在MySQL 5.6开始支持的一种根据索引进行查询的优化方式.之前的MySQL数据库版本不支持ICP,当进行索引查询是,首先根据索引来查找记录,然后在根据WHERE条件来过滤记录.在支持ICP后,MySQL数据库会在取出索引的同时,判断是否进行WHERE条件过滤,也就是将WHERE的部分过滤操作放在存储引擎层.在某些查询下,可以大大减少上层SQL层对记录的索取(fetch),从而提高整体性能 ICP优化支持range,ref,eq_ref,ref_or_null类型的查询,当前支持MyISAM和

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

本文出处:http://www.cnblogs.com/wy123/p/7374078.html(保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误进行修正或补充,无他) ICP优化原理 Index Condition Pushdown (ICP),也称为索引条件下推,体现在执行计划的上是会出现Using index condition(Extra列,当然Extra列的信息太多了,只能做简单分析)ICP原理通俗讲就是,查询过程中,直接在查询引擎

MySQL Index Condition Pushdown

Index Condition Pushdown (ICP)是MySQL 5.6 版本中的新特性,是一种在存储引擎层使用索引过滤数据的一种优化方式.[Index Condition Pushdown] 当关闭ICP时,index 仅仅是data access 的一种访问方式,存储引擎通过索引回表获取的数据会传递到MySQL Server 层进行where条件过滤.       当打开ICP时,如果部分where条件能使用索引中的字段,MySQL Server 会把这部分下推到引擎层,可以利用in

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

http://blog.itpub.net/22664653/viewspace-1210844/ -- 这篇博客写的更细,以后看 ICP(index condition pushdown)是mysql利用索引(二级索引)元组和筛字段在索引中的where条件从表中提取数据记录的一种优化操作.ICP的思想是:存储引擎在访问索引的时候检查筛选字段在索引中的where条件(pushed index condition,推送的索引条件),如果索引元组中的数据不满足推送的索引条件,那么就过滤掉该条数据记录

【MySQL】性能优化之 Index Condition Pushdown

一 概念介绍    Index Condition Pushdown (ICP)是MySQL 5.6 版本中的新特性,是一种在存储引擎层使用索引过滤数据的一种优化方式.a 当关闭ICP时,index 仅仅是data access 的一种访问方式,存储引擎通过索引回表获取的数据会传递到MySQL Server 层进行where条件过滤.b 当打开ICP时,如果部分where条件能使用索引中的字段,MySQL Server 会把这部分下推到引擎层,可以利用index过滤的where条件在存储引擎层进

MySQL ICP(Index Condition Pushdown)特性

一.SQL的where条件提取规则 在ICP(Index Condition Pushdown,索引条件下推)特性之前,必须先搞明白根据何登成大神总结出一套放置于所有SQL语句而皆准的where查询条件的提取规则:所有SQL的where条件,均可归纳为3大类:Index Key (First Key & Last Key),Index Filter,Table Filter. 接下来,简单说一下这3大类分别是如何定义,以及如何提取的,详情请看:SQL语句中where条件在数据库中提取与应用浅析.

【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 whi

MySQL 5.6新特性 -- Index Condition Pushdown

Index Condition Pushdown(ICP)是针对mysql使用索引从表中检索行数据时的一种优化方法. 在没有ICP特性之前,存储引擎根据索引去基表查找并将数据返回给mysql server,mysql server再根据where条件进行数据过滤. 有了ICP之后,在取出索引的同时,判断是否可以根据索引中的列进行where条件过滤,也就是将where的部分过滤操作放在了存储引擎层.这样就会减少上层sql层对记录的获取. ICP优化支持range.ref.eq_ref.ref_or

Index Condition Pushdown Optimization

Index Condition Pushdown (ICP) is an optimization for the case where MySQL retrieves rows from a table using an index(ICP是MySQL用索引从表中获取数据的一种优化). Without ICP, the storage engine traverses the index to locate rows in the base table and returns them to