深入了解 MySQL 的 EXPLAIN 命令

一、什么是 EXPLAIN 命令?

EXPLAIN 命令用于显示 MySQL 如何执行某个 SQL 语句,尤其是 SELECT 语句。通过 EXPLAIN 命令,可以看到查询在实际执行前的执行计划,这对于优化查询性能至关重要。

二、EXPLAIN 的基本用法

要使用 EXPLAIN 命令,只需在你的 SELECT 语句前加上 EXPLAIN 关键字即可。例如:

EXPLAIN SELECT * FROM employees WHERE department = 'Sales';

执行上述命令后,MySQL 会返回一个结果集,包含关于查询执行计划的详细信息。下面我们逐一解释这些信息。

三、EXPLAIN 结果各列的含义

EXPLAIN 命令的结果集通常包含以下几列:

  • id
  • select_type
  • table
  • partitions
  • type
  • possible_keys
  • key
  • key_len
  • ref
  • rows
  • filtered
  • Extra

id

id 列表示查询中每个 SELECT 子句的标识符。单个查询的 id 值通常是 1,子查询和联合查询的 id 值可能不同。

select_type

select_type 列表示 SELECT 的类型,常见的值有:

  • SIMPLE:简单的 SELECT 查询,不包含子查询或联合查询。
  • PRIMARY:最外层的 SELECT 查询。
  • UNION:UNION 中的第二个或后续的 SELECT 查询。
  • DEPENDENT UNION:UNION 中的第二个或后续的 SELECT 查询,依赖于外部查询。
  • UNION RESULT:UNION 的结果。
  • SUBQUERY:子查询中的第一个 SELECT。
  • DEPENDENT SUBQUERY:子查询中的第一个 SELECT,依赖于外部查询。
  • DERIVED:派生表(子查询的 FROM 子句)。

table

table 列表示正在访问的表的名称。

partitions

partitions 列表示查询涉及到的分区。如果表是分区表,此列将显示实际访问的分区。如果没有使用分区,该列显示 NULL

type(重点)

type 列表示连接类型(join type),反映了 MySQL 在执行查询时使用的访问方法。连接类型从最优到最差依次如下:

  • system:表仅有一行(等于系统表),这是 const 类型的特例。
  • const:表最多有一个匹配行,这是非常快速的,因为匹配行在优化阶段就读取出来了。使用索引一般是一般是 唯一索引 或 主键索引。
  • eq_ref:对于每个来自前一张表的行组合,读一行,这是最理想的连接类型。连接字段,使用索引一般是 唯一索引 或 主键索引。
  • ref:对于每个来自前一张表的行组合,读出所有匹配某个单独值的行。使用索引一般是普通索引。
  • range:检索给定范围内的行,使用一个索引来选择行。
  • index:全索引扫描(与全表扫描类似,但遍历索引树)。
  • ALL:全表扫描。

possible_keys

possible_keys 列表示查询可能使用的索引。

key(重点)

key 列表示实际使用的索引。如果没有选择索引,显示 NULL

key_len

key_len 列表示使用的索引键的长度。这个值是 MySQL 决定使用哪个索引时考虑的。

ref

ref 列表示使用哪个列或常量与 key 一起从表中选择行。

rows

rows 列表示 MySQL 估计为了找到所需的行,需要读取的行数。

filtered

filtered 列表示经过表条件过滤后返回的行数百分比。这个值表示剩余行数相对于读取的行数的百分比。计算公式为:filtered = (满足表条件的记录数 / 该表的总记录数) * 100%。

注意如果使用索引查询,那么 MySQL 可能不会扫全表,直接查出索引中返回的数据,filtered 会是 100。

Extra

Extra 列包含关于查询的详细信息,可能的值有:

  • Using index:只使用索引信息而不读取实际的行(覆盖索引)。
  • Using where:使用 WHERE 子句来限制哪些行将与下一张表匹配或返回给用户。
  • Using temporary:需要使用临时表来存储结果。
  • Using filesort:需要额外的传递来排序结果。

四、EXPLAIN 命令 type 字段 SQL 测试

4.1、const 类型测试

-- const 类型测试
drop table if exists user;
create table user (id int primary key,name varchar(20)
)engine=innodb;insert into user values(1,'ar414');
insert into user values(2,'zhangsan');
insert into user values(3,'lisi');
insert into user values(4,'wangwu');explain
select *
from user
where id = 1;

image-20240713155353388

4.2、eq_ref 类型测试

-- eq_ref 类型测试
drop table if exists user_balance;
drop table if exists user;create table user (id int primary key,name varchar(20)
)engine=innodb;insert into user values(1,'ar414');
insert into user values(2,'zhangsan');
insert into user values(3,'lisi');
insert into user values(4,'wangwu');create table user_balance (uid int primary key,balance int
)engine=innodb;insert into user_balance values(1,100);
insert into user_balance values(2,200);
insert into user_balance values(3,300);
insert into user_balance values(4,400);explain
select *
from userleft join user_balance on user.id = user_balance.uid
where user.id = user_balance.uid;

image-20240713155429390

4.3、ref 类型测试

-- ref 类型测试
drop table if exists user_balance;
drop table if exists user;create table user (id int primary key,name varchar(20)
)engine=innodb;insert into user values(1,'ar414');
insert into user values(2,'zhangsan');
insert into user values(3,'lisi');
insert into user values(4,'wangwu');create table user_balance (uid int,balance int,index(uid)
)engine=innodb;insert into user_balance values(1,100);
insert into user_balance values(2,200);
insert into user_balance values(3,300);
insert into user_balance values(4,400);
insert into user_balance values(5,500);explain
select *
from userleft join user_balance on user.id = user_balance.uid
where user.id = 1;explain select * from user_balance where uid = 1;

image-20240713155508580

4.4、range 类型测试

-- range 类型测试
drop table if exists user;create table user (id int primary key,name varchar(20)
)engine=innodb;insert into user values(1,'ar414');
insert into user values(2,'zhangsan');
insert into user values(3,'lisi');
insert into user values(4,'wangwu');explain
select *
from user
where id between 1 and 2;explain
select *
from user
where id in (1, 2, 3);explain
select *
from user
where id > 1;

image-20240713155627248

4.5、index 类型测试

-- index 类型测试
drop table if exists user;create table user (id int primary key,name varchar(20)
)engine=innodb;insert into user values(1,'ar414');
insert into user values(2,'zhangsan');
insert into user values(3,'lisi');
insert into user values(4,'wangwu');explain
select count(1)
from user;

image-20240713155701062

4.6、ALL 类型测试

-- ALL 类型测试
drop table if exists user;create table user (id int,name varchar(20)
)engine=innodb;insert into user values(1,'ar414');
insert into user values(2,'zhangsan');
insert into user values(3,'lisi');
insert into user values(4,'wangwu');
insert into user values(5,'zhaoliu');explain
select *
from user
where id = 1;

image-20240713155750163

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

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

相关文章

如何禁用键盘上的特定键或快捷方式?这里有详细步骤

要禁用特定的键盘键或快捷键吗?微软官方应用程序Microsoft PowerToys使这项任务变得非常简单。以下是使用Microsoft PowerToys中的键盘管理器禁用特定键或快捷方式的快速指南。 如果你还没有安装Microsoft PowerToys 如果你的设备上没有安装Microsoft PowerToys&a…

springboot上传图片

前端的name的值必须要和后端的MultipartFile 形参名一致 存储本地

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【匿名密钥证明(C/C++)】

匿名密钥证明(C/C) 在使用本功能时,需确保网络通畅。 在CMake脚本中链接相关动态库 target_link_libraries(entry PUBLIC libhuks_ndk.z.so)开发步骤 确定密钥别名keyAlias,密钥别名最大长度为64字节;初始化参数集:通过[OH_Huk…

css3 transform的旋转和位移制作太阳花

css3 transform 实例展示知识点rotate 旋转translate 位移transform: translate(300px,200px) rotate(90deg) 实例代码 实例展示 知识点 transform的两个属性 rotate 旋转 translate 位移 transform: translate(300px,200px) rotate(90deg) 实例代码 <!DOCTYPE html&g…

flask 定时任务(APScheduler)使用current_app app_context()上下文

前言: 描述&#xff1a;flask定时任务调用的方法中使用了current_app.logger.info()记录日志报错 报错代码 raise RuntimeError(unbound_message) from None RuntimeError: Working outside of application context.This typically means that you attempted to use functiona…

IDEA中Git常用操作及Git存储原理

Git简介与使用 Intro Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. Git是一款分布式版本控制系统&#xff08;VSC&#xff09;&#xff0c;是团队合作开发…

算法学习笔记(8.3)-(0-1背包问题)

目录 最常见的0-1背包问题&#xff1a; 第一步&#xff1a;思考每轮的决策&#xff0c;定义状态&#xff0c;从而得到dp表 第二步&#xff1a;找出最优子结构&#xff0c;进而推导出状态转移方程 第三步&#xff1a;确定边界条件和状态转移顺序 方法一&#xff1a;暴力搜素…

MFC之对话框--线宽/线型/颜色

文章目录 线宽输入实现优化无法记录上一次线粗问题 线宽滑动实现实现选择线类型实现颜色选择总结 线宽输入实现 优化无法记录上一次线粗问题 线宽滑动实现 实现选择线类型 实现颜色选择 总结 1。创建新窗口&#xff08;dialog)会创建一个新的类&#xff0c;在类中实现窗口中的…

vue中父子传递属性值

1、父传子属性值 自定义图库组件 在add.vue中应用tuku组件并给默认值 效果 2、 子传父&#xff0c;逆向赋值 add.vue和第一问中一样 修改tuku组件&#xff0c;传值给add.vue 3、多个传递 效果&#xff1a; 点击两个修改按钮后 4、使用defineModel简化父子传值 其他代码跟…

【postgresql】时间函数和操作符

日期/时间操作符 加减操作符&#xff1a; 和 - 可以用于日期、时间、时间戳和时间间隔的加减操作。 SELECT 2024-01-01::date INTERVAL 1 day as "date"; ; -- 结果&#xff1a;2024-01-02SELECT 2024-01-01 12:00:00::timestamp - INTERVAL 2 hours as "…

CSS上下悬浮特效

要实现一个上下悬浮的特效&#xff0c;可以使用CSS的keyframes规则和动画属性。以下是一个简单的示例&#xff1a; 代码示例 /* 定义一个名为floating的动画 */ keyframes floating {0% {transform: translateY(0); /* 初始位置 */}50% {transform: translateY(-4px); /* 向上…

KALI使用MSF攻击安卓设备

这期是kali使用MSF进行安卓渗透的保姆级别教程&#xff0c;话不多说&#xff0c;直接开始。 准备材料&#xff1a; 1.装有kali的实体机或虚拟机&#xff08;这里用实体机进行演示&#xff09; 2.一台安卓10.0以下的手机 打开kali&#xff0c;先用ifconfig查看自己的kali IP地址…

Python3极简教程(一小时学完)下

目录 PEP8 代码风格指南 知识点 介绍 愚蠢的一致性就像没脑子的妖怪 代码排版 缩进 制表符还是空格 每行最大长度 空行 源文件编码 导入包 字符串引号 表达式和语句中的空格 不能忍受的情况 其他建议 注释 块注释 行内注释 文档字符串 版本注记 命名约定 …

[BJDCTF2020]EasySearch1

知识点&#xff1a; 1.swp泄露 2.md5碰撞 3.PHP代码审计 4.SSI代码执行漏洞 // Apache SSI 远程命令执行漏洞复现 看着像sql注入&#xff0c;不过注入无果&#xff0c;扫一下目录试试~ 发现是swp泄露. SWP文件泄露漏洞是指在使用 Vim编辑器 编辑一个文件时&#xff0c;Vim会在…

OpenCV漫水填充函数floodFill函数的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 功能描述 ffloodFill函数是OpenCV库中用于图像处理的一个功能&#xff0c;它用于填充与种子点颜色相近的连通区域。这个函数在很多场景下都非常有用&#x…

MUR2060CTR-ASEMI无人机专用MUR2060CTR

编辑&#xff1a;ll MUR2060CTR-ASEMI无人机专用MUR2060CTR 型号&#xff1a;MUR2060CTR 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220 批号&#xff1a;最新 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;20A 最大循环峰值反向电压&#xff08;VRRM&#…

【数据结构】线性表----队列详解

1. 队列的基本概念 话不多说&#xff0c;直接开始&#xff01; 队列是一种线性数据结构&#xff0c;同栈类似但又不同&#xff0c;遵循先进先出&#xff08;FIFO, First In First Out&#xff09;的原则。换句话说&#xff0c;最先进入队列的元素会最先被移除。这样的特点使得…

小白学python(第七天)

哈哈&#xff0c;这个系列的文章也有一段时间没更新&#xff0c;主要是最近在忙c嘎嘎&#xff0c;不过没事接下来会优先更python啦&#xff0c;那么我们先进入正题吧 函数的定义及调用 函数定义 格式&#xff1a;def 函数名&#xff08;形参列表&#xff09;&#xff1a; 语…

QTabWidget、QListWidget、QStackedWidget

The QTabWidget class provides a stack of tabbed widgets. More... The QListWidget class provides an item-based list widget. More... QStringList strlist;strlist<<"系统"<<"外观"<<"截图"<<"贴图"…

Java的高级特性

类的继承 继承是从已有的类中派生出新的类&#xff0c;新的类能拥有已有类的属性和行为&#xff0c;并且可以拓展新的属性和行为 public class 子类 extends 父类{子类类体 } 优点 代码的复用 提高编码效率 易于维护 使类与类产生关联&#xff0c;是多态的前提 缺点 类缺乏独…