【MySQL了解MySQL的EXPLAIN,读这一篇够了( ̄∇ ̄)/

2023年 10月 18日 153.5k 0

The EXPLAIN statement provides information about how MySQL executes statements.

简单翻译下就是 EXPLAIN 提供 MySQL 如何执行语句的信息,我们举个例子

EXPLAIN SELECT name FROM app_user WHERE id = 1;

就是在你要执行的查询语句前加一个EXPLAIN,就可以查看执行当前语句的具体信息,比如属于什么查询类型啦~走了什么索引啦(具体如下图)~

总的来说,通过EXPLAIN我们可以获取以下信息:

  • 表的读取顺序
  • 数据读取操作的操作类型
  • 使用了哪些索引
  • 每张表优化器查询了多少行数据

【MySQL】了解MySQL的EXPLAIN,读这一篇够了( ̄∇ ̄)/-1​编辑

 我们在碰到一些类型“慢查询”问题时,一般会使用EXPLAIN来分析我们的SQL还有哪些地方可以做优化,具体就是根据上图中列表字段进行分析的,本篇就把EXPLAIN的关键字段挖个地儿朝天,👩再也不用担心要如何对SQL进行优化叻( ̄∇ ̄)/

ID

ID越大越先执行,一致按先后顺序执行

select_type 查询类型

这里只列出了常见的几种,想更加深入可以戳官网
dev.mysql.com/doc/refman/…https://dev.mysql.com/doc/refman/8.0/en/explain-output.html#explain_select_type

  • SIMPLE 简单查询(无联合查询或者子查询)
  • PRIMARY 复杂查询中最外层的select
  • DERIVED from后面的临时表(派生表)
  • SUBQUERY select后面的临时表
  • UNION union中第二个(或者说后一个)select

table 表名

表示结果集出自哪张表

举个🌰,如果某个查询table的值为<devired3>的含义就是这个select是从ID为3的派生表中进行查询的

type 关联类型/访问类型

类型 解释 备注
NULL 在优化阶段分解查询语句,使得在执行阶段无需再访问表/索引
system 无需进行磁盘IO,并且要查询的结果集只有一行记录 属于constant 的特殊情况
constant 查找主键索引,MySQL能对查询的某部分进行优化将其转换为一个常量(走主键(primary key)或者唯一(unique key)索引),所以表中最多有一个匹配行,只需要读取1次 - 可以使用show warnings;查看优化后的版本
eq_ref 查找唯一性索引,比如表链接时,使用主键/唯一索引进行关联的表查询,最多只会返回1条数据
ref 使用普通索引/非唯一性索引(从根节点开始),或者唯一性索引的部分前缀,索引要进行比较,有可能查出多条结果集 使用了联合主键前缀也是这种类型
range 查询某个索引的部分索引,范围扫描,通常出现在in()/between/>/</>=/<=等操作中,使用一个索引来检索指定范围 查询效率跟结果集大小相关(可使用分页等方式进行优化)
index (全索引扫描) 查找全部索引树,表示扫描全索引可以拿到结果(从1开始遍历),一半是扫描某个二级索引,这种扫描一般不会从索引树根节点开始快速查找,而是直接对二级索引的叶子节点遍历和扫描,速度还是比较慢的,这种查询一般会使用覆盖索引,二级索引一般比较小(主键索引包含数据,一般会比较大,因而读取的磁盘数据较大),所以index通常会比ALL快一些 如果主键索引和二级索引都包含结果集,MySQL会选用小的索引进行查询。虽然index也使用到了索引,但是和ref使用索引的方式不同,index是通过叶子节点从第一条索引开始向下遍历的,而ref是从索引的根节点开始折半查找,因而ref效率比index快很多ALL全表扫描,不使用任何索引,从第一个主键(聚簇索引的所有叶子节点)开始向下查找

possible_keys

MySQL觉得可能要用到的索引

key

实际用到的索引

key_len

用到的索引的长度(比如可用于判断使用了联合索引中的哪几个)

类型 具体类型 长度
字符串 char(n) n字节
varchar(n) 如果是utf-8则长度3n+2 字节,加的2字节用于存储字符串长度 utf-8一个占3字节
数值类型 tinyint 1字节
smallyint 2字节
int 4字节
bigint 8字节
时间类型 date 3字节
timestamp 4字节
NULL NULL 1字节 允许为空还有1个字段记录是否为空

一般来讲,索引的最大长度是768字节,当字符串过长时,MySQL会做一个类似左前缀索引的处理,将前半部分的字符串提取出来做索引

ref

表查找值所用的列(表名.字段)或常量(const)

这一列显示了在key列记录的索引中,表查找值所用到的列/常量

row

预估要读取并检测的行数

Extra

额外信息

  • Using index

查询结果集使用了覆盖索引(覆盖索引是一种查询方式,表示要查询的结果字段在查询的索引树中全部包括,无需再回表)

覆盖索引是指MySQL执行计划explain结果里的key有使用索引,如果select后面查询的字段都可以从这个索引树中获取,这种情况一般可以说是使用了覆盖索引,extra列中就会显示Using Index;覆盖索引一般针对的是辅助索引,整个查询结果只通过辅助索引就能拿到结果,不需要通过辅助索引树找到主键,再通过主键去主键索引树里获取其他字段值

优化点

如果出现回表的情况,即在查询字段中有一个字段没有加索引或者出现索引失效的问题,导致sql回表走了全表扫描,就可以使用覆盖索引进行优化

  • Using index condition

      查询的列不完全被索引覆盖,where条件之前一个前导列的范围

  • Using temporary/Using filesort

      使用了临时表

  • Using where

      使用Where语句处理结果,并且查询到的列未被索引覆盖

……

上面是一些常见的类型,其他还有很多,感兴趣可以参考官网

MySQL :: MySQL 8.0 Reference Manual :: 8.8.2 EXPLAIN Output Format

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论