MySQL 查询优化之 Index Condition Pushdown

Index Condition Pushdown限制条件

Index Condition Pushdown工作原理

ICP的开启与关闭

使用ICP示例

Index Condition Pushdown (ICP)是MySQL使用索引从表中检索行数据的一种优化方式。

  • 禁用ICP时,存储引擎会通过遍历索引定位基表中的行,然后返回给Server层,再去为这些数据行进行where条件的过滤。

  • 启用ICP时,如果where条件可以使用索引,MySQL会把这部分过滤操作放到存储引擎层,存储引擎通过索引过滤,把满足的行从表中读取出。 ICP可以减少存储引擎必须访问基表的次数以及Server曾必须访问存储引擎的次数。

1. Index Condition Pushdown限制条件

  • 当需要访问全表时,ICP用于range,ref,eq_ref和ref_or_null访问类型。

  • ICP可用于InnoDB和MyISAM表,包括分区的InnoDB和MyISAM表。

  • 对于InnoDB表,ICP仅用于辅助索引。ICP的目标是减少全行读取的数量,从而减少I/O操作。 对于InnoDB聚簇索引,完整记录已经读入InnoDB缓冲区。 在这种情况下使用ICP不会降低I/O.

  • 在虚拟生成列上创建的辅助索引不支持ICP。 InnoDB支持虚拟生成列的辅助索引。

  • 子查询的条件无法下推。

  • 存储函数的条件无法下推。存储引擎无法调用存储的函数。

  • 触发条件无法下推。

2. Index Condition Pushdown工作原理

1) 不使用ICP时,如何进行索引扫描

  • (1)当storage engine读取下一行时,首先读取索引元组(index tuple),然后使用索引元组在基表中(base table)定位和读取整行数据。

  • (2) sever层评估where条件,如果该行数据满足where条件则使用,否则丢弃。

  • (3)执行第1步,直到最后一行数据。

2)使用ICP时,如何进行索引扫描

  • (1)storage engine从索引中读取下一条索引元组。

  • (2) storage engine使用索引元组评估下推的索引条件。如果没有满足where条件,storage engine将会处理下一条索引元组(回到上一步)。只有当索引元组满足下推的索引条件的时候,才会继续去基表中读取数据。

  • (3)如果满足下推的索引条件,storage engine通过索引元组定位基表的行和读取整行数据并返回给server层。

  • (4)server层评估没有被下推到storage engine层的where条件,如果该行数据满足where条件则使用,否则丢弃。

3. ICP的开启与关闭

默认情况下启用Index Condition Pushdown 。可以通过设置optimizer_switch系统变量来控制它:

SET [GLOBAL|SESSION] optimizer_switch='command[,command]...';

SET optimizer_switch = 'index_condition_pushdown=off';
SET optimizer_switch = 'index_condition_pushdown=on';

用explain查看执行计划时,如果执行计划中的Extra信息为using index condition,表示优化器使用的index condition pushdown

4. 使用ICP示例

表结构定义

CREATE TABLE `address` (
`address_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`address` varchar(50) NOT NULL,
`address2` varchar(50) DEFAULT NULL,
`district` varchar(20) NOT NULL,
`city_id` smallint(5) unsigned NOT NULL,
`postal_code` varchar(10) DEFAULT NULL,
`phone` varchar(20) NOT NULL,
`location` geometry NOT NULL,
`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`address_id`),
KEY `idx_fk_city_id` (`city_id`),
SPATIAL KEY `idx_location` (`location`),
CONSTRAINT `fk_address_city` FOREIGN KEY (`city_id`) REFERENCES `city` (`city_id`) ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=606 DEFAULT CHARSET=utf8;

关闭ICP优化,Extra信息为“Using Where”

mysql> set optimizer_switch = "index_condition_pushdown=off";

mysql> explain select * from sakila.address d where d.city_id > 500;
+----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-------------+
| 1 | SIMPLE | d | NULL | range | idx_fk_city_id | idx_fk_city_id | 2 | NULL | 101 | 100.00 | Using where |
+----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

开启ICP之后,Extra信息为“Using Index Condition”

mysql> set optimizer_switch = "index_condition_pushdown=on";

mysql> explain select * from sakila.address d where d.city_id > 500;
+----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+
| 1 | SIMPLE | d | NULL | range | idx_fk_city_id | idx_fk_city_id | 2 | NULL | 101 | 100.00 | Using index condition |
+----+-------------+-------+------------+-------+----------------+----------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

MySQL 查询优化之 Index Condition Pushdown的更多相关文章

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

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

  2. MySQL索引与Index Condition Pushdown

    实际上,这个页面所讲述的是在MariaDB 5.3.3(MySQL是在5.6)开始引入的一种叫做Index Condition Pushdown(以下简称ICP)的查询优化方式.由于本身不是一个层面的 ...

  3. MySQL 5.6 Index Condition Pushdown

    ICP(index condition pushdown)是mysql利用索引(二级索引)元组和筛字段在索引中的where条件从表中提取数据记录的一种优化操作.ICP的思想是:存储引擎在访问索引的时候 ...

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

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

  5. MySQL ICP(Index Condition Pushdown)特性

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

  6. MySQL索引与Index Condition Pushdown(二)

    实验 先从一个简单的实验开始直观认识ICP的作用. 安装数据库 首先需要安装一个支持ICP的MariaDB或MySQL数据库.我使用的是MariaDB 5.5.34,如果是使用MySQL则需要5.6版 ...

  7. MySQL索引与Index Condition Pushdown(employees示例)

    实验 先从一个简单的实验开始直观认识ICP的作用. 安装数据库 首先需要安装一个支持ICP的MariaDB或MySQL数据库.我使用的是MariaDB 5.5.34,如果是使用MySQL则需要5.6版 ...

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

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

  9. MySQL 5.6新特性 -- Index Condition Pushdown

    Index Condition Pushdown(ICP)是针对mysql使用索引从表中检索行数据时的一种优化方法.   在没有ICP特性之前,存储引擎根据索引去基表查找并将数据返回给mysql se ...

随机推荐

  1. C#静态类、静态构造函数,类与结构体的比较

    一.静态类 静态类是不能实例化的,我们直接使用它的属性与方法,静态类最大的特点就是共享. 探究 public static class StaticTestClass{    public stati ...

  2. Guard Duty (medium) Codeforces - 958E2 || (bzoj 2151||洛谷P1792) 种树 || 编译优化

    https://codeforces.com/contest/958/problem/E2 首先求出N个时刻的N-1个间隔长度,问题就相当于在这些间隔中选K个数,相邻两个不能同时选,要求和最小 方法1 ...

  3. 接口测试02 - 无法绕过的json解析

    概述: 先瞧一下什么是json.JSON(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格式. 它基于ECMAScript(w3c定制的js规范)的一个子集 ...

  4. 097 Interleaving String 交错字符串

    给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的.例如,给定:s1 = "aabcc",s2 = "dbbca",当 s ...

  5. Python临时笔记

    动态语言python的特性 python2  输入一个匿名函数直接执行 # coding=utf-8 def Test(a, b, func): result = func(a, b) return ...

  6. nodejs项目报Process finished with exit code 8错误

    看控制台打印出来的错误:Error: listen EADDRNOTAVAIL  这是监听ip错误,没有该端口号. 修改IP地址,改成你所需要的ip地址 一般都是在自己本机上运行,所以把监听的ip改成 ...

  7. game 竞赛图 缩环

    [问题背景] zhx 和他的妹子(们)做游戏. [问题描述] 考虑 N 个人玩一个游戏, 任意两个人之间进行一场游戏 (共 N*(N-)/ 场) , 且每场一定能分出胜负. 现在,你需要在其中找到三个 ...

  8. mvc 连接数据库但单复值得问题

    1.  The model backing the ‘MusicStoreDBContext‘ context has changed since the database was created. ...

  9. 用户会话跟踪机制(session+cookie)

    最近在优化之前给学校写的一个项目,发现了同一个浏览器(IE,Firefox)开多个选项卡的时候不能登录多个用户,后一个登录用户会把前一个用户给覆盖了,我的登录逻辑是把user对象存放到session中 ...

  10. ES6中新增的字符串方法

    实例方法:includes(), startsWith(), endsWith() 传统上,JavaScript 只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中.ES6 又提供 ...