MySQL Index Condition Pushdown(ICP)优化
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了MySQL Index Condition Pushdown(ICP)优化,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4886字,纯文字阅读大概需要7分钟。
内容图文
![MySQL Index Condition Pushdown(ICP)优化](/upload/InfoBanner/zyjiaocheng/1090/6fb48c68f1144ef1993904b023c953e9.jpg)
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 inset (0.09 sec)
mysql>altertable employees addindex 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 inset (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 inset (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 inset (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;
原文:http://www.cnblogs.com/onlysun/p/4515335.html
内容总结
以上是互联网集市为您收集整理的MySQL Index Condition Pushdown(ICP)优化全部内容,希望文章能够帮你解决MySQL Index Condition Pushdown(ICP)优化所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。