当前位置:职场发展 > 【MySQL】了解MySQL的Explain,读这一篇够了( ̄∇ ̄)/

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

  • 发布:2023-09-18 19:04

目录

ID

select_type 查询类型

table 表名

type 关联类型/访问类型

possible_keys MySQL觉得可能要用到的索引

key 实际用到的索引

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

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

row 预估要读取并检测的行数

Extra 额外信息

The EXPLAIN statement provides information about how MySQL executes statements.

EXPLAIN提供MySQL如何执行语句的信息,举个例子

EXPLAIN SELECT name FROM app_user WHERE id = 1;

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

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

ID

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

select_type 查询类型

这里只列出了常见的几种,想更加深入可以戳官网

https://www.sychzs.cn/doc/refman/8.0/en/explain-output.html#explain_select_typehttps://www.sychzs.cn/doc/refman/8.0/en/explain-output.html#explain_select_type

  • SIMPLE 简单查询(无联合查询或者子查询)

  • PRIMARY 复杂查询中最外层的select

  • DERIVED from后面的临时表(派生表)

  • SUBQUERY select后面的临时表

  • UNION union中第二个(或者说后一个)select

table 表名

表示结果集出自哪张表

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

type 关联类型/访问类型

类型

解释

备注

NULL

在优化阶段分解查询语句,使得在执行阶段无需再访问表/索引

system

要查询的结果集只有一行记录

属于constant 的特殊情况

constant

MySQL能对查询的某部分进行优化将其转换为一个常量(走主键(primary key)或者唯一(unique key)索引),所以表中最多有一个匹配行,只需要读取1次

  • 可以使用show warnings;查看优化后的版本

  • dual 是MySQL内部自己定义的一张空表(为了符合语法)

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

相关文章