Mysql执行计划字段解释

文章目录

  • 一、前言
  • 二、如何查看执行计划
  • 三、执行计划各字段解释
  • 四、select_type
    • 4.1、SIMPLE(简单查询)
      • 4.1.1、简单的单表查询
      • 4.1.2、多表连接查询
    • 4.2、PRIMARY(主查询)
      • 4.2.1、包含复杂子查询的外层查询
      • 4.2.2、UNION语句中的第一个查询
    • 4.3、SUBQUERY(子查询)、DEPENDENT SUBQUERY(依赖子查询)、UNCACHEABLE SUBQUERY(不可缓存子查询)
      • 4.3.1、SUBQUERY(子查询)
      • 4.3.2、DEPENDENT SUBQUERY(依赖子查询)
      • 4.3.3、UNCACHEABLE SUBQUERY(不可缓存子查询)
    • 4.4、UNION(合并查询)、UNION RESULT(合并查询结果)、DEPENDENT UNION(依赖合并查询)、UNCACHEABLE UNION(不可缓存合并查询)
      • 4.4.1、UNION(合并查询)、UNION RESULT(合并查询结果)
      • 4.4.2、DEPENDENT UNION(依赖合并查询)
      • 4.4.3、UNCACHEABLE UNION(不可缓存合并查询)
    • 4.5、DERIVED(派生表)
    • 4.6、MATERIALIZED(物化)
  • 五、type
    • 5.1、system
    • 5.2、const
    • 5.3、eq_ref
    • 5.4、ref
    • 5.5、fulltext
    • 5.6、ref_or_null
    • 5.7、index_merge
    • 5.8、unique_subquery
    • 5.9、index_subquery
    • 5.10、range
    • 5.11、index
    • 5.12、ALL
  • 六、Extra
    • 6.1、Using index
    • 6.2、Using where
    • 6.3、Using temporary
    • 6.4、Using filesort
    • 6.5、Using index condition

一、前言

每次遇到 sql 优化,查看执行计划,其中的字段是什么含义总是会忘,所以有了这篇文章方便查阅。

二、如何查看执行计划

第一种方法,在 SELECT 语句前面加上 EXPLAIN 关键字

image-20230720151221683

第三种方法,如果用 Navicat 数据库工具的话,点击上面的解释按钮

image-20230720151150027

三、执行计划各字段解释

先贴上 Mysql 官方文档中关于执行计划字段解释的地址:

官网:MySQL 8.0 Reference Manual / Optimization / Understanding the Query Execution Plan / EXPLAIN Output Format

中文网:MySQL 8.0 参考手册 / 第8章优化 / 8.8 了解查询执行计划 / 8.8.2 EXPLAIN 输出格式

字段说明
id操作的唯一标识符
select_type操作的类型
table涉及的表名
partitions操作涉及的分区
type表示使用的连接类型或扫描类型
possible_keys可能使用的索引列表
key实际选择使用的索引
key_len索引键的长度
ref连接条件所使用的列或常量
rows估计的扫描行数
filtered从结果中过滤返回行的百分比
Extra额外的信息

下面就结合一些实际例子看下 select_type、type、Extra

准备脚本如下:

– 创建用户表
CREATE TABLE user (
id int(11) NOT NULL AUTO_INCREMENT ,
name varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
age int(11) NULL DEFAULT NULL ,
dept_id int(11) NULL DEFAULT NULL ,
remark text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
PRIMARY KEY (id),
INDEX index_name_age (name, age) USING BTREE ,
INDEX index_dept_id (dept_id) USING BTREE ,
FULLTEXT INDEX index_remark (remark)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
AUTO_INCREMENT=38
ROW_FORMAT=DYNAMIC
;

– 初始化用户数据
INSERT INTO user (id, name, age, dept_id, remark) VALUES (‘1’, ‘张三’, ‘20’, ‘1’, ‘abc’);
INSERT INTO user (id, name, age, dept_id, remark) VALUES (‘2’, ‘李四’, ‘18’, ‘1’, ‘bcd’);
INSERT INTO user (id, name, age, dept_id, remark) VALUES (‘3’, ‘王五’, ‘22’, ‘1’, ‘cde’);
INSERT INTO user (id, name, age, dept_id, remark) VALUES (‘4’, ‘赵六’, ‘23’, ‘2’, ‘def’);
INSERT INTO user (id, name, age, dept_id, remark) VALUES (‘5’, ‘孙七’, ‘25’, ‘2’, ‘efg’);
INSERT INTO user (id, name, age, dept_id, remark) VALUES (‘6’, ‘周八’, ‘16’, ‘2’, ‘fgh’);
INSERT INTO user (id, name, age, dept_id, remark) VALUES (‘7’, ‘吴九’, ‘19’, ‘3’, ‘ghi’);
INSERT INTO user (id, name, age, dept_id, remark) VALUES (‘8’, ‘郑十’, ‘13’, ‘3’, ‘hij’);

– 创建部门表
CREATE TABLE dept (
id int(11) NOT NULL ,
name varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
PRIMARY KEY (id),
INDEX index_name (name) USING BTREE
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
ROW_FORMAT=DYNAMIC
;

– 初始化部门数据
INSERT INTO dept (id, name) VALUES (‘1’, ‘人事部’);
INSERT INTO dept (id, name) VALUES (‘2’, ‘财务部’);
INSERT INTO dept (id, name) VALUES (‘3’, ‘技术部’);

四、select_type

select_type说明
SIMPLE简单查询
PRIMARY主查询(外部查询)
SUBQUERY子查询
DEPENDENT SUBQUERY依赖子查询
UNCACHEABLE SUBQUERY不可缓存子查询
UNION合并查询
UNION RESULT合并查询结果
DEPENDENT UNION依赖合并查询
UNCACHEABLE UNION不可缓存合并查询
DERIVED派生表
MATERIALIZED物化

下面针对各种情况举例,不用纠结sql本身的业务含义

4.1、SIMPLE(简单查询)

不包含UNION或者子查询

4.1.1、简单的单表查询

EXPLAIN SELECT * FROM user;

image-20230720182617026

4.1.2、多表连接查询

EXPLAIN SELECT
a.* , b.*
FROM
USER a
INNER JOIN dept b ON b.id = a.dept_id;

4.2、PRIMARY(主查询)

包含复杂子查询的外层查询,或者UNION语句中的第一个查询

4.2.1、包含复杂子查询的外层查询

EXPLAIN SELECT
*
FROM
(
SELECT
*
FROM
USER
WHERE
id = 1
UNION ALL
SELECT
*
FROM
USER
WHERE
id = 2
) x

image-20230721111030923

4.2.2、UNION语句中的第一个查询

EXPLAIN SELECT
*
FROM
USER
WHERE
id = 1
UNION ALL
SELECT
*
FROM
USER
WHERE
id = 2

image-20230721111225371

4.3、SUBQUERY(子查询)、DEPENDENT SUBQUERY(依赖子查询)、UNCACHEABLE SUBQUERY(不可缓存子查询)

  • SUBQUERY(子查询):子查询是指嵌套在主查询中的查询语句。当 Mysql 优化器将子查询作为单独的查询执行,并将结果作为主查询的条件之一时,select_type 会被标记为 SUBQUERY 。这种情况下,子查询会在主查询之前执行,并将结果传递给主查询使用。
  • DEPENDENT SUBQUERY(依赖子查询):当一个子查询需要根据外部查询的结果来确定查询条件或提供必要的数据时,它就被称为依赖子查询。依赖子查询会在外部查询的每一行上执行,并根据外部查询的结果进行计算。
  • UNCACHEABLE SUBQUERY(不可缓存子查询):优化器可以根据查询中的各种条件和索引信息来对查询进行优化,以获得更好的性能。然而,某些类型的子查询由于其特殊的性质,无法被优化器缓存。

4.3.1、SUBQUERY(子查询)

如果是SUBQUERY(子查询)需要满足以下条件:

  1. 子查询不能转化为半连接,关于半连接可参考:8.2.2.1 使用半连接转换优化 IN 和 EXISTS 子查询谓词
  2. 子查询是不相关子查询

这里补充下不相关子查询相关子查询的含义

不相关子查询:子查询与主查询之间没有依赖关系,独立于主查询执行,只执行一次,然后将结果用于主查询的条件或者计算

相关子查询:子查询与主查询之间存在依赖关系,子查询的结果依赖于主查询的每一行数据

EXPLAIN SELECT
*
FROM
USER
WHERE
age > (SELECT avg(age) FROM USER)

image-20230724133742111

4.3.2、DEPENDENT SUBQUERY(依赖子查询)

如果是DEPENDENT SUBQUERY(依赖子查询)需要满足以下条件:

  1. 子查询不能转化为半连接
  2. 子查询是相关子查询

只要把上面例子里的 > 改成 IN,子查询就会变成相关子查询

EXPLAIN SELECT
*
FROM
USER
WHERE
age IN (SELECT avg(age) FROM USER)

image-20230724144341329

4.3.3、UNCACHEABLE SUBQUERY(不可缓存子查询)

当子查询中使用了不支持查询缓存的函数,会导致该子查询被标记为不可缓存

EXPLAIN SELECT
(
SELECT
id
FROM
USER
ORDER BY
RAND()
LIMIT 1
) AS random_user
FROM
DUAL;

image-20230724150507705

4.4、UNION(合并查询)、UNION RESULT(合并查询结果)、DEPENDENT UNION(依赖合并查询)、UNCACHEABLE UNION(不可缓存合并查询)

  • UNION(合并查询):在 UNION 语句中,第二个及之后的 select 会标记成 UNION。
  • UNION RESULT(合并查询结果):当执行 UNION 操作时,MySQL 可能会生成一个 UNION RESULT 来存储合并后的结果集,以供后续处理使用,这个结果集就会标记为 UNION RESULT。
  • DEPENDENT UNION(依赖合并查询):依赖于外部查询的 UNION 操作,UNION 的结果取决于外部查询的结果,无法独立地进行计算,通常表现为子查询中,第二个及之后的 select。
  • UNCACHEABLE UNION(不可缓存合并查询):和 UNCACHEABLE SUBQUERY(不可缓存子查询)类似,表示一个无法通过查询缓存来进行优化的 UNION 操作。

4.4.1、UNION(合并查询)、UNION RESULT(合并查询结果)

EXPLAIN SELECT
*
FROM
USER
WHERE
id = 1
UNION
SELECT
*
FROM
USER
WHERE
id = 2

image-20230721142623017

4.4.2、DEPENDENT UNION(依赖合并查询)

当UNION作为子查询时,第二个或者后面的查询语句

EXPLAIN SELECT
*
FROM
USER
WHERE
id IN (
SELECT
id
FROM
USER
WHERE
NAME = ‘张三’
UNION ALL
SELECT
id
FROM
USER
WHERE
NAME = ‘李四’
);

image-20230725110243771

4.4.3、UNCACHEABLE UNION(不可缓存合并查询)

EXPLAIN SELECT
*
FROM
USER
WHERE
id IN (
SELECT
id
FROM
USER
WHERE
NAME = ‘张三’
UNION
SELECT
id
FROM
USER
WHERE
NAME <> ‘张三’
ORDER BY
RAND()
)

image-20230725110331726

4.5、DERIVED(派生表)

在查询中使用子查询生成的临时表

EXPLAIN SELECT
u.dept_id,
u.avgAge
FROM
(
SELECT
dept_id,
avg(age) avgAge
FROM
USER
WHERE
id > 3
GROUP BY
dept_id
) AS u
WHERE
u.avgAge > 20;

image-20230724174348276

4.6、MATERIALIZED(物化)

当查询包含子查询或派生表,并且优化器认为将其结果保存到临时表中会更有效率时,就会使用物化表。使用物化表可以避免在每次引用子查询或派生表时都需要重新计算结果集,从而提高查询性能。特别是当子查询或派生表的结果集较大或计算复杂时。

五、type

type说明
system该表只有一行(相当于系统表),system是const类型的特例
const键或唯一索引的等值查询,最多只返回一行数据
eq_ref当使用了索引的全部组成部分,并且索引是PRIMARY KEY或UNIQUE NOT NULL 才会使用该类型
ref如果仅使用了索引的最左边前缀,或者索引不是PRIMARY KEY或UNIQUE
fulltext全文索引
ref_or_null和ref类似,但是会额外搜索哪些行包含了NULL
index_merge使用索引合并优化
unique_subquery和eq_ref类似,但是使用了IN查询,且子查询是主键或者唯一索引
index_subquery和unique_subquery类似,只是子查询使用的是非唯一索引
range仅检索给定范围内的行,使用索引来选择行,可以在使用 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, LIKE, 或 IN()等操作符。
index与ALL类似,只是扫描了索引树
ALL全表扫描

性能从优到劣依次为:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

5.1、system

该表只有一行(相当于系统表),system是const类型的特例

5.2、const

键或唯一索引的等值查询,最多只返回一行数据

EXPLAIN SELECT
*
FROM
USER
WHERE
id = 1

image-20230725102043213

5.3、eq_ref

当使用了索引的全部组成部分,并且索引是PRIMARY KEY或UNIQUE NOT NULL 才会使用该类型

EXPLAIN SELECT
u.* , d.*
FROM
USER u
INNER JOIN dept d ON d.id = u.dept_id
WHERE
u. NAME = ‘张三’;

image-20230725110040061

5.4、ref

如果仅使用了索引的最左边前缀,或者索引不是PRIMARY KEY或UNIQUE

EXPLAIN SELECT
*
FROM
USER
WHERE
NAME = ‘张三’;

image-20230725110123874

5.5、fulltext

全文索引

EXPLAIN SELECT
*
FROM
USER
WHERE
MATCH (remark) AGAINST (‘c*’ IN boolean MODE);

image-20230725104629982

5.6、ref_or_null

和ref类似,但是会额外搜索哪些行包含了NULL

EXPLAIN SELECT
*
FROM
USER
WHERE
NAME = ‘zhangsan’
OR NAME IS NULL;

image-20230725105121498

5.7、index_merge

使用索引合并优化

EXPLAIN SELECT
*
FROM
USER
WHERE
id = ‘1’
OR NAME = ‘张三’;

image-20230725110842295

5.8、unique_subquery

和eq_ref类似,但是使用了IN查询,且子查询是主键或者唯一索引

5.9、index_subquery

和unique_subquery类似,只是子查询使用的是非唯一索引

5.10、range

仅检索给定范围内的行,使用索引来选择行,可以在使用 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, LIKE, 或 IN()等操作符。

EXPLAIN SELECT
*
FROM
USER
WHERE
id > 5;

image-20230725131152637

5.11、index

与ALL类似,只是扫描了索引树

5.12、ALL

全表扫描

六、Extra

这里列出一些常见的,其他的参考官方文档

6.1、Using index

查询使用了覆盖索引,查询的所有列都可以从索引中获取,而不需要回表查询数据行。

EXPLAIN SELECT
id
FROM
USER
WHERE
id = 1;

image-20230725140007277

6.2、Using where

在执行查询时会使用WHERE子句对结果进行进一步的筛选,或者全表扫描

EXPLAIN SELECT
*
FROM
USER
WHERE
age > 18;

image-20230725140306128

6.3、Using temporary

为了解析查询,MySQL 需要创建一个临时表来保存结果。

EXPLAIN SELECT
NAME
FROM
USER
WHERE
id = 1
UNION
SELECT
NAME
FROM
USER
WHERE
id = 2

image-20230725140533806

6.4、Using filesort

无法使用索引或其他优化方式直接按照查询语句中的顺序返回结果,而是需要额外的排序操作。会对性能产生一定影响,特别是对大数据量的查询语句。

EXPLAIN SELECT
*
FROM
USER
ORDER BY
age
LIMIT 10;

image-20230725140628343

6.5、Using index condition

表示查询使用了索引条件过滤数据,通常表示使用了索引下推,是一个好的优化迹象

索引下推:指 MySQL 将 WHERE 条件中可用于索引的部分推到存储引擎层级进行处理,而不是等到存储引擎返回数据行后再应用 WHERE 条件进行过滤。这样可以减少 IO 操作和数据传输,提高查询性能。

EXPLAIN SELECT
*
FROM
USER
WHERE
NAME = ‘张三’
AND age > 18;

image-20230725140242178

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/8637.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自动化测试框架unittest与pytest的区别!

引言 前面文章已经介绍了python单元测试框架&#xff0c;大家平时经常使用的是unittest&#xff0c;因为它比较基础&#xff0c;并且可以进行二次开发&#xff0c;如果你的开发水平很高&#xff0c;集成开发自动化测试平台也是可以的。而这篇文章主要讲unittest与pytest的区别&…

可解释的 AI:在transformer中可视化注意力

Visualizing Attention in Transformers | Generative AI (medium.com) 一、说明 在本文中&#xff0c;我们将探讨可视化变压器架构核心区别特征的最流行的工具之一&#xff1a;注意力机制。继续阅读以了解有关BertViz的更多信息&#xff0c;以及如何将此注意力可视化工具整合到…

Debian12中为python3配置虚拟环境及在Pycharm中使用虚拟环境

在Debian 12中&#xff0c;python默认为python 3.11。 基于应用&#xff0c;现需设置虚拟环境。 1.安装venv模块 从python3.3开始&#xff0c;配置python虚拟环境&#xff0c;可用venv模块&#xff0c;更加方便了。 执行命令&#xff1a; #apt install python3.11-venv 2.…

Java虚拟机——前端编译优化

Java的编译期是有上下文语境影响的&#xff0c;不同语境下可以指不同的过程&#xff1a; 可以是前端编译器&#xff0c;把*.java文件转变成*.class文件的过程。 JDK的Javac、Eclipse JDT中的增量式编译器 可以指Java虚拟机的即时编译器&#xff08;JIT编译器&#xff09;在运…

【算法基础:搜索与图论】3.6 二分图(染色法判定二分图匈牙利算法)

文章目录 二分图介绍染色法判定二分图例题&#xff1a;860. 染色法判定二分图 匈牙利匹配二分图最大匹配匈牙利匹配算法思想例题&#xff1a;861. 二分图的最大匹配 二分图介绍 https://oi-wiki.org/graph/bi-graph/ 二分图是图论中的一个概念&#xff0c;它的所有节点可以被…

FPGA驱动SPI屏幕(附完整工程)

一. 简介 相信大家都玩过屏幕&#xff0c;在FPGA上使用最多的就是VGA/HDMI接口的显示器了&#xff0c;这两种显示器的优点就不用说了&#xff0c;缺点就是体积比较大&#xff0c;而且价格比较贵&#xff0c;对于追求便携/价格低的我来说&#xff0c;SPI接口的屏幕才是我的首要…

更新合集 | 七月功能上新记

点击链接了解详情 七月来临&#xff0c;正式开启 2023 下半年的新征途&#xff01;这个盛夏&#xff0c;腾讯云 CODING 上线了微信扫码注册、微信通知、Go 制品管理等重点能力&#xff0c;为企业及团队研发管理带来更多便利&#xff01;以下是 CODING 新功能速递&#xff0c;快…

登录页的具体实现 (小兔鲜儿)【Vue3】

登录页 整体认识和路由配置 整体认识 登录页面的主要功能就是表单校验和登录登出业务 准备模板 <script setup></script><template><div><header class"login-header"><div class"container m-top-20"><h1 cl…

详解go的hex.Encode原理

简言 今天看nsq的messageID生成的时候&#xff0c;发现它使用了hex.Encode函数来产生编码&#xff0c;那就顺道研究一下这个编码方式。 原理 hex是16进制的意思&#xff0c;encode是进行编码的意思&#xff0c;内部实现也很简单&#xff0c;就是 每4位计算出十六进制的值&a…

基于Python机器学习、深度学习在气象、海洋、水文等技能提升教程

详情点击链接&#xff1a;基于Python机器学习、深度学习技术提升气象、海洋、水文领域实践应用 前言 Python是功能强大、免费、开源&#xff0c;实现面向对象的编程语言&#xff0c;能够在不同操作系统和平台使用&#xff0c;简洁的语法和解释性语言使其成为理想的脚本语言。…

数据可视化(1)

使用python带的matplotlib库进行简单的绘图。使用之前先进行安装&#xff0c;pip install matplotlib。如果安装了Anaconda,则无需安装matplotlib。 1.简单折线图 #绘制简单图表 import matplotlib.pyplot as plt plt.plot([1,2,3,4,5]) plt.show() import matplotlib.pyp…

2023年的深度学习入门指南(19) - LLaMA 2源码解析

2023年的深度学习入门指南(19) - LLaMA 2源码解析 上一节我们学习了LLaMA 2的补全和聊天两种API的使用方法。本节我们来看看LLaMA 2的源码。 补全函数text_completion源码解析 上一节我们讲了LLaMA 2的编程方法。我们来复习一下&#xff1a; generator Llama.build(ckpt_di…

logback-spring.xml日志配置文件详解

目录 前言logback-spring.xml 配置 前言 打印日志是一个系统的基本功能&#xff0c;系统出现异常可以通过查找日志弄清楚是什么原因&#xff0c;从而更加快速地定位问题&#xff0c;修复系统。 logback-spring.xml 配置 文件位置 具体配置 <?xml version"1.0"…

MGRE实验

实验步骤 第⼀步&#xff1a;IP地址规划 PC地址 设备地址 第⼆步&#xff1a;配置IP地址 R1配置 [R1]interface g0/0/0 [R1-GigabitEthernet0/0/0]ip address 192.168.1.1 24 [R1]interface s4/0/0 [R1-Serial4/0/0]ip address 15.1.1.1 24 R2配置 [R2]interface g0/0/…

TCP实现原理和为什么需要三次握手?两次握手不可以?四次握手不可以?

TCP实现原理和为什么需要三次握手?两次握手不可以?四次握手不可以? 1. 什么是TCP协议? TCP&#xff1a;Transmission Control Protocol翻译过来就是传输控制协议,TCP协议是一个面向连接的、可靠的、基于字节流的传输层协议RFC 793对TCP连接的定义 > Connections: >…

Windows 在VMware16.x安装Win11系统详细教程

文章目录 一、准备二、创建虚拟机1. 创建新的虚拟机2. 选择虚拟机硬件兼容性3. 安装客户机操作系统4. 选择客户机操作系统5. 命名虚拟机6. 固件类型7. 处理器配置8. 此虚拟机内存9. 网络类型10. 选择I/O控制器类型11. 选择磁盘类型12. 选择磁盘13. 指定磁盘容量14. 指定磁盘文件…

Centos7.6安装RocketMQ4.9.2并配置开机自启

1、下载RocketMQ 编译后的压缩包 wget https://dlcdn.apache.org/rocketmq/4.9.2/rocketmq-all-4.9.2-bin-release.zip2、解压 unzip rocketmq-all-4.9.2-bin-release.zip3、进入解压文件夹 cd rocketmq-all-4.9.2/4、编辑配置文件/usr/local/rocketmq/rocketmq-all-4.9.4-…

Docker-Compose 轻松搭建 Grafana+InfluxDb 实用 Jmeter 监控面板

目录 前言&#xff1a; 1、背景 2、GranfanaInfluxDB 配置 2.1 服务搭建 2.2 配置 Grafana 数据源 2.3 配置 Grafana 面板 3、Jmeter 配置 3.1 配置 InfluxDB 监听器 3.2 实际效果 前言&#xff1a; Grafana 和 InfluxDB 是两个非常流行的监控工具&#xff0c;它们可…

Java网络编程(一)基本网络概念

一、网络 网络(network) 是几乎可以实时相互发送和接收数据的计算机和其他设备的集合。网络通常用线缆连接&#xff0c;数据位转换为电磁波&#xff0c;通过线缆移动。不过&#xff0c;无线网络会通过无线电波传输数据&#xff0c;许多长距离的传输现在会用通过玻璃纤维发送可见…