认真学习MySQL中的索引条件下推(ICP)

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介: 认真学习MySQL中的索引条件下推(ICP)

① 什么是ICP


Index Condition Pushdown(ICP)是MySQL5.6中新特性,是一种在存储引擎层使用索引过滤数据的优化方式。


MySQL的执行计划(Explain)中,我们有时会在Extra列中看到 Using index condition。其就是表示索引条件下推(ICP)。


如果没有ICP,存储引擎会遍历索引以定位基表中的行,并将它们返回给MySQL服务器,由MySQL服务器评估where后面的条件是否保留行。


启用ICP后,如果部分 where 条件可以仅使用索引中的列进行筛选,则MySQL服务器会把这部分 where 条件放到存储引擎筛选。然后,存储引擎通过使用索引条目来筛选数据,并且只有在满足这一条件时才从表中读取行。


好处:ICP可以减少存储引擎必须访问基表的次数和MySQL服务器必须访问存储引擎的次数。

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

ICP的开启和关闭

默认情况下启用索引条件下推。可以通过设置系统变量 optimizer_switch 来控制index_condition_pushdown

index_merge=on,index_merge_union=on,
index_merge_sort_union=on,index_merge_intersection=on,
engine_condition_pushdown=on,
index_condition_pushdown=on,
mrr=on,mrr_cost_based=on,block_nested_loop=on,
batched_key_access=off,materialization=on,
semijoin=on,loosescan=on,firstmatch=on,
duplicateweedout=on,subquery_materialization_cost_based=on,
use_index_extensions=on,
condition_fanout_filter=on,derived_merge=on


开启和关闭:

# 开启
set optimizer_switch='index_condition_pushdown=on';
# 关闭
set optimizer_switch='index_condition_pushdown=off';

③ ICP实例

如下所示,表people中有联合索引KEYzip_last_first (zipcode,lastname,firstname) ,当我们执行如下SQL时,就会触发ICP。

EXPLAIN SELECT * FROM people
WHERE zipcode='000001'
AND lastname LIKE '%张%'
AND address LIKE '%北京市%';


执行查看SQL的查询计划,Extra中显示了Using index condition ,这表示使用了索引下推。另外,Using where表示条件中包含需要过滤的非索引列的数据,即 address like ‘%北京市%’ 这个标记并不是索引列,需要在服务端过滤掉。



这个如何理解呢?


按照我们的认知,其首先使用索引zipcode='000001'查找,然后回表到主键索引(聚簇索引)中进行查找。假设有1000条,那么我们需要回表1000次并将数据读取到内存中再进行 lastname LIKE '%张%' 和 address LIKE '%北京市%'的过滤。毕竟 lastname LIKE '%张%'按照我们前面的学习,是用不到索引的。


如果MySQL服务器用了ICP,联合索引中包含了lastname,那么就可以在二级索引查找的时候就同时进行zipcode='000001 AND lastname LIKE '%张%'的过滤,假设这时得到100条数据。那么就只需要回表100次,再进行address LIKE '%北京市%' 的过滤。


也就是ICP减少了回表次数,也同时减少了回表读取数据导致的随机IO次数。


那么对于可以正常使用联合索引的SQL呢?如下所示

EXPLAIN SELECT * FROM people
WHERE zipcode='000001'
AND lastname LIKE '张%'
AND firstname LIKE '三%';

按照我们的理解,是可以正常使用到索引的。但是查看执行计划,其Extra仍然存在Using index condition。不过查看此时的key_len能够发现确实是用到了三个字段索引。


可以自己做一下测试,数据量比较大的时候分别在两种情况下(是否使用ICP)验证查询性能,如下图所示没有ICP的查询明显要慢一些。


④ ICP的使用条件


如果表访问的类型为range、ref、eq_ref 和 ref_or_null 可以使用ICP

ICP可以用于InnoDB 和 MyISAM表,包括分区表InnoDB和MyISAM表

对于InnoDB表,ICP仅用于二级索引。ICP的目标是减少全行读取次数,从而减少IO操作。

当SQL使用覆盖索引时,不支持ICP。因为这种情况下使用ICP不会减少IO。

相关子查询的条件不能使用ICP。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
7月前
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
7月前
|
存储 关系型数据库 MySQL
MySQL数据库索引的数据结构?
MySQL中默认使用B+tree索引,它是一种多路平衡搜索树,具有树高较低、检索速度快的特点。所有数据存储在叶子节点,非叶子节点仅作索引,且叶子节点形成双向链表,便于区间查询。
215 4
|
9月前
|
存储 关系型数据库 MySQL
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
|
4月前
|
NoSQL 算法 Redis
【Docker】(3)学习Docker中 镜像与容器数据卷、映射关系!手把手带你安装 MySql主从同步 和 Redis三主三从集群!并且进行主从切换与扩容操作,还有分析 哈希分区 等知识点!
Union文件系统(UnionFS)是一种**分层、轻量级并且高性能的文件系统**,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem) Union 文件系统是 Docker 镜像的基础。 镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
614 5
|
11月前
|
关系型数据库 MySQL 数据库
Mysql的索引
MYSQL索引主要有 : 单列索引 , 组合索引和空间索引 , 用的比较多的就是单列索引和组合索引 , 空间索引我这边没有用到过 单列索引 : 在MYSQL数据库表的某一列上面创建的索引叫单列索引 , 单列索引又分为 ● 普通索引:MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一点。 ● 唯一索引:索引列中的值必须是唯一的,但是允许为空值 ● 主键索引:是一种特殊的唯一索引,不允许有空值 ● 全文索引: 只有在MyISAM引擎、InnoDB(5.6以后)上才能使⽤用,而且只能在CHAR,VARCHAR,TEXT类型字段上使⽤用全⽂文索引。
|
5月前
|
关系型数据库 MySQL 数据管理
Mysql基础学习day03-作业
本内容包含数据库建表语句及多表查询示例,涵盖内连接、外连接、子查询及聚合统计,适用于员工与部门数据管理场景。
103 1
|
5月前
|
SQL 关系型数据库 MySQL
Mysql基础学习day01
本课程为MySQL基础学习第一天内容,涵盖MySQL概述、安装、SQL简介及其分类(DDL、DML、DQL、DCL)、数据库操作(查询、创建、使用、删除)及表操作(创建、约束、数据类型)。适合初学者入门学习数据库基本概念和操作方法。
219 6
|
5月前
|
SQL 关系型数据库 MySQL
Mysql基础学习day02-作业
本教程介绍了数据库表的创建与管理操作,包括创建员工表、插入测试数据、删除记录、更新数据以及多种查询操作,涵盖了SQL语句的基本使用方法,适合初学者学习数据库操作基础。
122 0
|
5月前
|
SQL 关系型数据库 MySQL
Mysql基础学习day03
本课程为MySQL基础学习第三天内容,主要讲解多表关系与多表查询。内容涵盖物理外键与逻辑外键的区别、一对多、一对一及多对多关系的实现方式,以及内连接、外连接、子查询等多表查询方法,并通过具体案例演示SQL语句的编写与应用。
159 0
|
5月前
|
SQL 关系型数据库 MySQL
Mysql基础学习day01-作业
本教程包含三个数据库表的创建练习:学生表(student)要求具备主键、自增长、非空、默认值及唯一约束;课程表(course)定义主键、非空唯一字段及数值精度限制;员工表(employee)包含自增主键、非空字段、默认值、唯一电话号及日期时间类型字段。每个表的结构设计均附有详细SQL代码示例。
109 0

推荐镜像

更多