首页 > 数据库 >MySQL查询性能优化七种武器之索引下推

MySQL查询性能优化七种武器之索引下推

时间:2022-12-15 18:07:46浏览次数:57  
标签:name 七种 下推 查询 索引 MySQL 主键

​​MySQL查询性能优化七种武器之索引潜水​​

​​MySQL查询性能优化七种武器之链路追踪​​

今天要讲的是MySQL的另一种查询性能优化方式 — 索引下推(Index Condition Pushdown,简称ICP),是MySQL5.6版本增加的特性。

1. 索引下推的作用

主要作用有两个:

  1. 减少回表查询的次数
  2. 减少存储引擎和MySQL Server层的数据传输量

总之就是了提升MySQL查询性能。

2. 案例实践

创建一张用户表,造点数据验证一下:

CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(100) NOT NULL COMMENT '姓名',
`age` tinyint NOT NULL COMMENT '年龄',
`gender` tinyint NOT NULL COMMENT '性别',
PRIMARY KEY (`id`),
KEY `idx_name_age` (`name`,`age`)
) ENGINE=InnoDB COMMENT='用户表';

在 姓名和年龄 (​​name​​​,​​age​​) 两个字段上创建联合索引。

查询SQL执行计划,验证一下是否用到索引下推

explain select * from user where name='一灯' and age>2;

MySQL查询性能优化七种武器之索引下推_MySQL

执行计划中的Extra列显示了Using index condition,表示用到了索引下推的优化逻辑。

3. 索引下推配置

查看索引下推的配置:

show variables like '%optimizer_switch%';

如果输出结果中,显示 index_condition_pushdown=on,表示开启了索引下推

也可以手动开启索引下推

set optimizer_switch="index_condition_pushdown=on";

关闭索引下推

set optimizer_switch="index_condition_pushdown=off";

4. 索引下推原理剖析

索引下推在底层到底是怎么实现的?

是怎么减少了回表的次数?

又减少了存储引擎和MySQL Server层的数据传输量?

在没有使用索引下推的情况,查询过程是这样的:

  1. 存储引擎根据where条件中name索引字段,找到符合条件的3个主键ID
  2. 然后二次回表查询,根据这3个主键ID去主键索引上找到3个整行记录
  3. 把数据返回给MySQL Server层,再根据where中age条件,筛选出符合要求的一行记录
  4. 返回给客户端

画两张图,就一目了然了。

下面这张图是回表查询的过程:

  1. 先在联合索引上找到name=‘一灯’的3个主键ID
  2. 再根据查到3个主键ID,去主键索引上找到3行记录

MySQL查询性能优化七种武器之索引下推_Server_02

下面这张图是存储引擎返回给MySQL Server端的处理过程:

MySQL查询性能优化七种武器之索引下推_主键_03

我们再看一下在使用索引下推的情况,查询过程是这样的:

  1. 存储引擎根据where条件中name索引字段,找到符合条件的3行记录,再用age条件筛选出符合条件一个主键ID
  2. 然后二次回表查询,根据这一个主键ID去主键索引上找到该整行记录
  3. 把数据返回给MySQL Server层
  4. 返回给客户端

MySQL查询性能优化七种武器之索引下推_MySQL_04

MySQL查询性能优化七种武器之索引下推_Server_05

现在是不是理解了索引下推的两个作用:

  1. 减少回表查询的次数
  2. 减少存储引擎和MySQL Server层的数据传输量

索引下推的含义就是,本来在MySQL Server层做的筛选操作,下推到存储引擎层来做。

5. 索引下推应用范围

  1. 适用于InnoDB 引擎和 MyISAM 引擎的查询
  2. 适用于执行计划是range, ref, eq_ref, ref_or_null的范围查询
  3. 对于InnoDB表,仅用于非聚簇索引。索引下推的目标是减少全行读取次数,从而减少 I/O 操作。对于 InnoDB聚集索引,完整的记录已经读入InnoDB 缓冲区。在这种情况下使用索引下推 不会减少 I/O。
  4. 子查询不能使用索引下推
  5. 存储过程不能使用索引下推

再附一张Explain执行计划详解图:

MySQL查询性能优化七种武器之索引下推_Server_06

 

​​MySQL查询性能优化七种武器之索引潜水​​

​​MySQL查询性能优化七种武器之链路追踪​​

今天要讲的是MySQL的另一种查询性能优化方式 — 索引下推(Index Condition Pushdown,简称ICP),是MySQL5.6版本增加的特性。

1. 索引下推的作用

主要作用有两个:

  1. 减少回表查询的次数
  2. 减少存储引擎和MySQL Server层的数据传输量

总之就是了提升MySQL查询性能。

2. 案例实践

创建一张用户表,造点数据验证一下:

CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(100) NOT NULL COMMENT '姓名',
`age` tinyint NOT NULL COMMENT '年龄',
`gender` tinyint NOT NULL COMMENT '性别',
PRIMARY KEY (`id`),
KEY `idx_name_age` (`name`,`age`)
) ENGINE=InnoDB COMMENT='用户表';

在 姓名和年龄 (​​name​​​,​​age​​) 两个字段上创建联合索引。

查询SQL执行计划,验证一下是否用到索引下推

explain select * from user where name='一灯' and age>2;

MySQL查询性能优化七种武器之索引下推_MySQL

执行计划中的Extra列显示了Using index condition,表示用到了索引下推的优化逻辑。

3. 索引下推配置

查看索引下推的配置:

show variables like '%optimizer_switch%';

如果输出结果中,显示 index_condition_pushdown=on,表示开启了索引下推

也可以手动开启索引下推

set optimizer_switch="index_condition_pushdown=on";

关闭索引下推

set optimizer_switch="index_condition_pushdown=off";

4. 索引下推原理剖析

索引下推在底层到底是怎么实现的?

是怎么减少了回表的次数?

又减少了存储引擎和MySQL Server层的数据传输量?

在没有使用索引下推的情况,查询过程是这样的:

  1. 存储引擎根据where条件中name索引字段,找到符合条件的3个主键ID
  2. 然后二次回表查询,根据这3个主键ID去主键索引上找到3个整行记录
  3. 把数据返回给MySQL Server层,再根据where中age条件,筛选出符合要求的一行记录
  4. 返回给客户端

画两张图,就一目了然了。

下面这张图是回表查询的过程:

  1. 先在联合索引上找到name=‘一灯’的3个主键ID
  2. 再根据查到3个主键ID,去主键索引上找到3行记录

MySQL查询性能优化七种武器之索引下推_Server_02

下面这张图是存储引擎返回给MySQL Server端的处理过程:

MySQL查询性能优化七种武器之索引下推_主键_03

我们再看一下在使用索引下推的情况,查询过程是这样的:

  1. 存储引擎根据where条件中name索引字段,找到符合条件的3行记录,再用age条件筛选出符合条件一个主键ID
  2. 然后二次回表查询,根据这一个主键ID去主键索引上找到该整行记录
  3. 把数据返回给MySQL Server层
  4. 返回给客户端

MySQL查询性能优化七种武器之索引下推_MySQL_04

MySQL查询性能优化七种武器之索引下推_Server_05

现在是不是理解了索引下推的两个作用:

  1. 减少回表查询的次数
  2. 减少存储引擎和MySQL Server层的数据传输量

索引下推的含义就是,本来在MySQL Server层做的筛选操作,下推到存储引擎层来做。

5. 索引下推应用范围

  1. 适用于InnoDB 引擎和 MyISAM 引擎的查询
  2. 适用于执行计划是range, ref, eq_ref, ref_or_null的范围查询
  3. 对于InnoDB表,仅用于非聚簇索引。索引下推的目标是减少全行读取次数,从而减少 I/O 操作。对于 InnoDB聚集索引,完整的记录已经读入InnoDB 缓冲区。在这种情况下使用索引下推 不会减少 I/O。
  4. 子查询不能使用索引下推
  5. 存储过程不能使用索引下推

再附一张Explain执行计划详解图:

MySQL查询性能优化七种武器之索引下推_Server_06

标签:name,七种,下推,查询,索引,MySQL,主键
From: https://blog.51cto.com/smallfa/5945565

相关文章

  • 4:数据操作-MySQL
    (目录)4.1插入数据1.插入数据insertinto表名(可以省略)values(不可省略的内容)mysql>insertintoteacher(id,name,phone,address)values(1,'Frank','188888......
  • liunx 系统 mysql 登录初始化
    1.初始化密码登录1.1查看初始化密码: 输入指令  #cat/var/log/mysqld.log日志记录里有初始化密码,复制密码保存登录数据库再修改 ......
  • k8s创建MySQL
    Kubernetes创建MysQL整体流程:创建数据存储PV、PVC;创建MySQL数据库、创建访问入口Service;导入测试数据库test-db创建数据存储PV、PVC这里我们使用nfs作为storageclass......
  • MySQL数据管理
    MySQL数据管理1.外键(了解)在创建表的时候,增加约束CREATETABLE`grade`( `gradeid`INT(10)NOTNULLAUTO_INCREMENTCOMMENT'年级id', `gradename`VARCHAR(50)N......
  • mysql binlog日志自动清理及手动删除
    说明当开启mysql数据库主从时,会产生大量如mysql-bin.00000*log的文件,这会大量耗费您的硬盘空间。如:mysql-bin.000001mysql-bin.000002mysql-bin.000003mysql-bin.0......
  • MySQL函数
    常用函数--数学运算SELECTABS(-8)--绝对值SELECTCEILING(7.8)--向上取整SELECTFLOOR(7.8)--向下取整SELECTRAND()--返回0~1随机数SELECTSIGN(0)--......
  • Docker学习笔记十二:Docker安装MySQL
    下载命令:dockerpullmysql:5.7安装可参考Docker Hub官网说明的镜像的用法  安装 不挂载目录启动容器创建容器命令:dockerrun-d--name=mysql1-p3307:......
  • 离线安装mysql5.7【教程二】
    openjdk1.8文件下载链接地址:链接:https://pan.baidu.com/s/1fLt_dNILuw5VsV_PcA_yAQ提取码:ot3emysql5.7安装包下载链接地址:链接:https://pan.baidu.com/s/1du7Dk7WtJ0Ac......
  • MySQL必知必会:用十一张图讲清楚,当你CRUD时BufferPool中发生了什么!以及BufferPool的优
    一、收到了大佬们的建议1、篇幅偏短,建议稍微加长一点。这点说的确实挺对,有的篇幅确实比较短,针对这个提议我会考虑将相似的话题放在一篇文章中。但是这可能会导致我中断每天......
  • 谈谈MySQL的基数统计
    **目录​​推荐阅读方式​​​​一、基数是啥?​​​​二、InnoDB更新基数的时机?​​​​三、基数是估算出来​​​​四、持久化基数​​​​四、如何主动更新基数?​​​​推......