你不得不知的MYSQL优化——索引下推

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 你不得不知的MYSQL优化——索引下推

前言


说到MySQL的优化手段,不得不提的是MYSQL5.6中引入的一种新特性,索引下推,英文是 index condition pushdown,一般简称为 ICP。这也是MySQL面试中经常被问到的一个考点,本文就此分享下索引下推是怎么一回事,它是如何对提高查询效率起到帮助的。


理解索引下推


索引下推就是指在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数来提高查询效率。

如何理解呢? 我们直接上栗子来解释:

  1. 新建用户表
CREATE TABLE user(
     `id` int NOT NULL AUTO_INCREMENT,
     `zipcode` varchar(20) DEFAULT NULL,
     `name` varchar(20) DEFAULT NULL,
     `address` varchar(50) DEFAULT NULL,
     PRIMARY KEY (`id`),
     index idx_zip_name(`zipcode`, `name`)
) ENGINE=INNODB;
insert into user(zipcode, name, address)
values ('100001', '陈旭阳', '杭州'),
       ('100001', '胡歌', '上海'),
       ('200002', '杨幂', '北京'),
       ('300002', '刘诗诗', '南京');
  • 创建了基于邮编zipcode和名称name的联合索引idx_zip_name,用于查找某个邮编下,名字包含陈的人。
  1. 查询语句
select * from user where zipcode = '100001' and name like '%陈%' and address like '%余杭%';
  • 查询条件根据zipcode精确查找,nameaddress全模糊匹配。

如果MySQL5.6以前, 没有索引下推特性,整个流程如下图:

1671199612586.jpg

  • 联合索引中知道100001的数据项,因为name是全模糊,无法走索引,address压根没有索引,他们无法在联合索引中过滤,怎么办?只能回到数据最全的聚簇索引上进行name like '%陈%' and address like '%余杭%'这个逻辑的过滤。
  • 按照上面的方式,每次回到聚簇索引这个一个称做 “回表” 的过程,势必增加磁盘IO,从而影响查询性能。

那么有什么办法可以优化呢?

优化的目标就是尽量减少回表这一过程,我们发现联合索引上竟然有了name字段的信息,为什么我们不能充分利用呢? name like '%陈%'我们可以直接在索引树上进行判断name是不是包含陈,从而减少回表次数。这也正是MySQL5.6中优化的特性,如下图所示:


1671199621200.jpg


  • 根据查询条件name like '%陈%'陈旭阳包含了陈, 那么它去回表过滤address内容。
  • 而其他记录比如胡歌等不包含陈,那么其他记录就无需回表,再次去匹配address地址是否符合了,相当于减少了回表。

上面图中的索引都用表格表示,只是为了方便,实际上索引底层数据结构是B+数据,如果不了解的,可以阅读文章:一步步带你设计MySQL索引数据结构

一句话总结:索引下推(index condition pushdown,ICP),有效的减少了回表次数,提高了查询效率。


索引下推性能比较


竟然索引下推可以提高效率,那我们验证下。

  1. 沿用上面的user表
  2. 创建存储过程,添加数据
DELIMITER //
CREATE PROCEDURE insert_user(max_num INT)
BEGIN
DECLARE i INT DEFAULT 0;
    SET autocommit = 0;
    REPEAT
    SET i = i + 1;
    INSERT INTO user(zipcode,name,address) VALUES ('10018', '陈旭阳', '杭州');
    UNTIL i =max_num
END REPEAT;
COMMIT;
END //
DELIMITER ;
  1. 调用存储过程
call insert_user(1000000);
  1. 打开性能检查工具profiling
set profiling = 1;
  1. 启用索引下推方式查询
select * from user where zipcode = '10018' and name like '%李%';
  1. 禁用索引下推方式查询
select /*+ no_icp(user) */ * from user where zipcode = '10018' and name like '%李%';
  1. 查看当前会话下的profiles
show profiles;
  1. 结果如下:
  • 有索引下推0.21s

1671199652003.jpg

  • 没有索引下推花了2.6s

1671199666001.jpg

使用ICP性能提高还是比较明显的,特别是数据量大的情况下。


执行计划中的索引下推


如何判断你的SQL中是否使用了到索引下推的特性呢?

我们利用explain查看SQL的执行计划时,如果发现Extra字段中有Using index condition,即表示使用到了索引下推。

1671199685457.jpg

注意如果发现一直没有用上索引下推,需要检查下功能是否被禁用,默认是打开的。

  • 可以通过设置系统变量optimizer_switch控制:index_condition_pushdown
# 打开索引下推
SET optimizer_switch = 'index_condition_pushdown=on';
# 关闭索引下推
SET optimizer_switch = 'index_condition_pushdown=off';


总结


本文介绍了索引下推特性,并简要分析了它的实现原理。虽然说,这个特性MySQL支持了,但是为什么我们还要学习理解它呢,因为它对于我们如何写SQL、如何创建索引还是起着指导作用的。如果本文对你有帮助的话,请留下一个赞吧。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
5天前
|
存储 关系型数据库 MySQL
MySQL索引失效及避免策略:优化查询性能的关键
MySQL索引失效及避免策略:优化查询性能的关键
22 3
|
10天前
|
关系型数据库 MySQL 数据库
MySQL删除全局唯一索引unique
这篇文章介绍了如何在MySQL数据库中删除全局唯一的索引(unique index),包括查看索引、删除索引的方法和确认删除后的状态。
32 9
|
5天前
|
缓存 关系型数据库 MySQL
MySQL数据库优化:提升性能和扩展性的关键技巧
MySQL数据库优化:提升性能和扩展性的关键技巧
14 2
|
5天前
|
存储 SQL 关系型数据库
MySQL 的索引是怎么组织的?
MySQL 的索引是怎么组织的?
11 1
|
5天前
|
存储 关系型数据库 MySQL
MySQL索引的概念与好处
本文介绍了MySQL存储引擎及其索引类型,重点对比了MyISAM与InnoDB引擎的不同之处。文中详细解释了InnoDB引擎的自适应Hash索引及聚簇索引的特点,并阐述了索引的重要性及使用原因,包括提升数据检索速度、实现数据唯一性等。最后,文章还讨论了主键索引的选择与页分裂问题,并提供了使用自增字段作为主键的建议。
MySQL索引的概念与好处
|
5天前
|
监控 关系型数据库 MySQL
如何优化MySQL数据库的索引以提升性能?
如何优化MySQL数据库的索引以提升性能?
14 0
|
5天前
|
监控 关系型数据库 MySQL
深入理解MySQL数据库索引优化
深入理解MySQL数据库索引优化
12 0
|
18天前
|
NoSQL 关系型数据库 MySQL
微服务架构下的数据库选择:MySQL、PostgreSQL 还是 NoSQL?
在微服务架构中,数据库的选择至关重要。不同类型的数据库适用于不同的需求和场景。在本文章中,我们将深入探讨传统的关系型数据库(如 MySQL 和 PostgreSQL)与现代 NoSQL 数据库的优劣势,并分析在微服务架构下的最佳实践。
|
20天前
|
存储 SQL 关系型数据库
使用MySQL Workbench进行数据库备份
【9月更文挑战第13天】以下是使用MySQL Workbench进行数据库备份的步骤:启动软件后,通过“Database”菜单中的“管理连接”选项配置并选择要备份的数据库。随后,选择“数据导出”,确认导出的数据库及格式(推荐SQL格式),设置存储路径,点击“开始导出”。完成后,可在指定路径找到备份文件,建议定期备份并存储于安全位置。
160 11
|
15天前
|
存储 SQL 关系型数据库
MySQL的安装&数据库的简单操作
本文介绍了数据库的基本概念及MySQL的安装配置。首先解释了数据库、数据库管理系统和SQL的概念,接着详细描述了MySQL的安装步骤及其全局配置文件my.ini的调整方法。文章还介绍了如何启动MySQL服务,包括配置环境变量和使用命令行的方法。最后,详细说明了数据库的各种操作,如创建、选择和删除数据库的SQL语句,并提供了实际操作示例。
58 13
MySQL的安装&数据库的简单操作
下一篇
无影云桌面