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

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

时间:2022-08-26 11:14:49浏览次数:61  
标签:name 七种 下推 查询 索引 MySQL 主键

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

1. 索引下推的作用

主要作用有两个:

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

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

2. 案例实践

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

1 2 3 4 5 6 7 8 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;

 

 

 执行计划中的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端的处理过程:

 

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

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

 

 

 

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

  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执行计划详解图:

 

标签:name,七种,下推,查询,索引,MySQL,主键
From: https://www.cnblogs.com/zt0313/p/16626879.html

相关文章

  • mysql8.0.30安装
    1.下载 MySQL::DownloadMySQLCommunityServer   2.安装执行mysqldinstall提示安装成功   3.初始化data(安装目录下是没有data的,执行此命令后......
  • 《八股文》MySQL核心问题总结(一)
      作为SQLBoy,基础部分不会有人不会吧?面试也不怎么问,基础掌握不错的小伙伴可以跳过这一部分。当然,可能会现场写一些SQL语句,SQ语句可以通过牛客、LeetCode、LintCode之......
  • arm架构安装mysql5.7
    添加mysql用户组和mysql用户,用于隔离mysql进程groupadd-rmysql&&useradd-r-gmysql-s/sbin/nologin-Mmysql2.安装依赖库yuminstall-ylibaio*下载解压M......
  • Debian 11 安装 MySQL 8.0.30
    阿里云轻量级服务器Debian11安装MySQL8.0.30一、从官网下载MySQL8.0.30的64位压缩包sudowgethttps://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.30-......
  • Mysql和Redis数据如何保持一致
    先阐明一下Mysql和Redis的关系:Mysql是数据库,用来持久化数据,一定程度上保证数据的可靠性;Redis是用来当缓存,用来提升数据访问的性能。关于如何保证Mysql和Redis中的数据一致......
  • Python——pymysql(连接mysql数据库)
    基本设置(包括预防SQL注入):SQL注入问题,在写入sql语言时,可能会有利用mysql语句来进行正常输入的规避。importpymysqlconn=pymysql.connect(host='127.0.0.1',user......
  • mysql主从复制
    主配置[mysqld]#主数据库端ID号server_id=1#开启二进制日志log-bin=mysql-bin#需要复制的数据库名,如果复制多个数据库,重复设置这......
  • Mysql——运维
    慢日志可以进行对数据库系统查询方面大于设定值进行的日志记录。慢日志-执行时间>10-未命中索引-日志文件路径配置:-内存showvariablesli......
  • Mysql入门练习题
    1、在students表中,查询年龄大于25岁,且为男性的同学的名字和年龄mysql>selectname,agefromstudentswhereage>25andgender='M';+---------------+-----+|name......
  • MySql数据库
    MySql数据库概述MySQL是一个基于Sql结构化查询语言的关系型数据库,由瑞典MySQLAB公司开发,目前属于Oracle公司。数据类型数值类型inttinyint、smallint、mediumi......