MySQL中Explain用法详解

article/2025/9/29 14:47:20

Explain简介

我们在写后端程序的时候,通常会写sql来查询数据,如果是单表查询的时候,那直接select就完事了,但是如果是连表查询数据量也不小的话,就造成了查询速度会比较慢,那么我们该怎么知道我的sql的实际执行情况,它有没有走索引,执行效率是啥呢?数据库就给我们提供了这么一种功能,这个就是本文的重点了:expalin。

通过explain,我们可以获取到sql语句的执行计划,比如像表的读取顺序,使用了哪些索引等等。但是各个数据库的explain执行计划所展示出的内容是不太相同的,这里我们就来看MySQl中的执行计划explain。

先来跑两行SQL作为本文的例子:

CREATE TABLE `project` (`id` int(12) NOT NULL,`project_name` varchar(32) DEFAULT NULL,PRIMARY KEY (`id`),KEY `idx_name` (`project_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;insert into  project (id,project_name) 
values ('1', 'project1 '), 
('2', 'projectplus'),
('3','projectpro');CREATE TABLE `student` (`id` int(12) NOT NULL,`name` varchar(32) DEFAULT NULL COMMENT '姓名',`project_id` int(12) DEFAULT NULL COMMENT '课程编码',PRIMARY KEY (`id`),KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;insert into student (id,name,project_id) 
values ('1','name1','1'),
('2','nameplus','2'),
('3','namepro','3');

我们来执行一条最简单的sql,一探expalin结果的究竟。

explain SELECT * from student

控制台:

在这里插入图片描述

可以看到,显示出来的参数还是很多的,那这些都是什么意思呢?接下来我们一个一个来进行分析一下。

id

id这一列代表sql语句执行的顺序,id值越大的行,越先执行,id值相同的情况下,执行顺序就从上往下执行。一般来说,有多少个select,就会有多少个id。

select_type

这个从字面意思来看呢。就是查询类型,它主要就是来区别普通查询、联合查询、子查询等。

他有六种类型:

  1. Simple:简单查询,查询不包含子查询和union

    explain SELECT * from student:可以看到,这个sql的explain执行计划上的select_type就是simple

在这里插入图片描述

  1. Primary:对于union、union all、子查询的大查询,最左侧的就是primary,复杂查询中最外层的select

    explain SELECT * from student union select * from student

  2. Derived:包含在from子句中的子查询,MySQL会将结果存放在一个临时表中,也称为派生表

    explain SELECT * from (SELECT s1.* from student s1 union SELECT s2.* from student s2) k

  3. Union:在union中的第二个和随后的select()

    其实3、4、5可以使用同一条sql:

在这里插入图片描述

  1. Union result:从union临时表检索结果的select

  2. Subquery:包含在select中的子查询(不在from子句中),select查的字段中的信息。

    explain SELECT student.*,(SELECT name from student where name=‘name1’) from student where name=‘name1’

table

这个就是当前行所执行的表,当然了,如果表定义了别名的话,那么就会显示别名。

Partitions

分区,也就是查询的表所在的分区,如果是NULL的话,就代表该表没有被设置分区。

type

该行查询所使用的访问类型,他的值有十多种,但是这些我们没有必要全部知道,这里我列出来最常见的八种,这八种类型的效率就代表从好到差:

  1. System:这个是效率最高的,比如像where id=xxxx,但是在这里有个点我要说一下,就是啥吧,在MySQL5.7版本之前使用这类sql是可以出现System类型的,但是在5.7版本之后呢,就不会出现这个System类型了,转而是以Const类型来替代,也就是下面这种。

  2. Const:mysql能对查询部分进行优化并将其转化为常量,用于primary key或者unique key的所有列与常数比较时,所以表最多只有一个匹配行,读取一次,速度比较快,

    对primary key或者unique key字段进行的查询,就是const

    select * from (select *from film where id=1)tmp;

  3. eq_ref:primary key或者unique key索引的所有部分被连接使用,最多只会返回一条符合条件的记录,这是在const之外最好的连接类型了,简单的select查询不会出现这种type

    使用join进行连表查询时,对unique key或者primary key字段进行关联条件

    explain SELECT * from student left join project on student.project_id=project.id

  4. Ref:代表在非唯一性索引或者非主键上进行的查询。

    EXPLAIN SELECT * from student where name=‘name1’

  5. Ref_or_null,与上面类似,但是可以搜索值为null的行

    EXPLAIN SELECT * from student where name=‘namepro’ or name is null

  6. Range:范围扫描,一般在in、between、>、<、>=等情况下使用,使用一个索引来检索给定范围的行。

    EXPLAIN SELECT * from student where id>1

  7. Index:即使全表扫描,我们在表中也设置有主键索引,此时会走索引,

    select count(*) from student

  8. All:全表扫描

    EXPLAIN SELECT * from student

    一般保证查询至少达到range级别,最好能达到ref。

possible_keys

表示该行查询可能使用到的查询索引,它是理论上的,某些情况下,是与实际用的索引不同的。

key

上面是可能使用到的索引,而这个呢,就是该行实际使用到的索引。

key len

表示索引中所使用的字节数,可通过该列计算查询中使用的索引长度。在不损失精确性的情况下,长度越短越好。key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,并不是通过表内检索出的。

ref

显示关联的字段。如果使用常数等值查询,则显示const,如果是连接查询,则会显示关联的字段。

rows

rows列代表该行查询所涉及到多少行数据,而非最终的结果。

Filered

这个是个百分比,rowsfiltered的值与前表产生交互,比如rows是1000,filtered是10,那么就说明会有10000*0.1=100的值与前表交互,

返回结果的行数占查询的行数的比例

explain SELECT * from student where id=‘1’

Extra

这一列展示的是额外信息。

Using index:表示使用索引,但是select的字段需要设置索引,如果有order by的话,那么order by里面的字段也要设置了索引。

explain select name from student order by name

Using where:使用where语句。

explain select * from student where id > 1;

Using temporary:使用临时表

explain select distinct project_id from student;这种就是Using temporary,因为表中没有distinct project_id这种字段,因此是先建立个临时表,然后对这个临时表来进行去重,这种一般是需要优化的,首先可以使用索引来进行优化。

Using filesort:采用文件扫描对结果进行计算排序,效率很差,对于排序,只有select字段与order by字段都被覆盖的话,才允许使用Using index

Explain select * from student order by name(Using filesort)

总结

以上呢就是关于MySQL的explain执行计划的内容了,虽然他的显示出来的字段是比较多的,但是其实它是有的是重要的,有的则是不那么重要,因此我们其实是没有必要每一列都要彻底搞清楚的。在这里我列几个个人觉得相对重要的属性:id、type、key、ref、extra。如果需要对sql进行优化的话,着重关注这几个就可以。


http://chatgpt.dhexx.cn/article/vj5aYbLe.shtml

相关文章

【MySQL】explain 用法详解

【MySQL】explain 用法详解 explain命令主要来查看SQL语句的执行计划&#xff0c;查看该SQL语句有没有使用索引&#xff0c;有没有做全表扫描等。它可以模拟优化器执行SQL查询语句&#xff0c;从而知道MySQL是如何处理用户的SQL语句。 文章目录 【MySQL】explain 用法详解一、e…

Explain详解

目录 一、表信息 二、explain 的两种使用方式 三、explain中的列 1. id列 2. select_type列 3. table列 4. type列 5. possible_keys列 6. key列 7. key_len列 8. ref列 9. rows列 10. Extra列 四、索引最佳实践 使用EXPLAIN关键字可以模拟优化器执行SQL语句&…

mysql 用法 Explain

前言&#xff1a;explain&#xff08;执行计划&#xff09;&#xff0c;使用explain关键字可以模拟优化器执行sql查询语句&#xff0c;从而知道MySQL是如何处理sql语句。explain主要用于分析查询语句或表结构的性能瓶颈。 注&#xff1a;本系列随笔如无特殊说明都MySQL版本都为…

Mysql中explain的用法详解

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

explain用法和结果分析

1. EXPLAIN简介 使用EXPLAIN关键字可以模拟优化器执行SQL查询语句&#xff0c;从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。 通过explain我们可以获得以下信息&#xff1a; 表的读取顺序数据读取操作的操作类型哪些索引可以使用哪些索引被实…

Explain使用详解

在日常开发工作中&#xff0c;对于SQL的书写&#xff0c;通常都会尽量让SQL能够使用到表中创建的索引&#xff0c;以此来提高SQL语句的性能。想要参看一个SQL是否会使用索引&#xff0c;可以使用MySQL字段的分析工具Explain&#xff0c;这篇文章重要介绍该工具的使用。 一、 简…

EXPLAIN 的用法

用法简介 EXPLAIN 的用法很简单&#xff0c;只需要在你的 SQL 前面加上 EXPLAIN 即可。例如&#xff1a; explain select * from t; PS&#xff1a;insert、update、delete 同样可以通过 explain 查看执行计划&#xff0c;不过通常我们更关心 select 的执行情况 你会看到如下…

[MySQL高级](一) EXPLAIN用法和结果分析

1. EXPLAIN简介 使用EXPLAIN关键字可以模拟优化器执行SQL查询语句&#xff0c;从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。 ➤ 通过EXPLAIN&#xff0c;我们可以分析出以下结果&#xff1a; 表的读取顺序数据读取操作的操作类型哪些索引可…

.NET6.0的日志组件Log4net

前言&#xff1a;不允许让没有任何日志监控的项目上线&#xff0c;所以说真正开发起来必须要有监控&#xff0c;相当于多一双眼睛帮着我们看项目在运行时会不会有什么问题&#xff0c;我们要不断的在每个环节写日志&#xff0c;这样发生异常我们可以快速知道哪里有问题了&#…

Unity接入日志插件Log4Net

前言 log4net是一个日志插件&#xff0c;可以帮助我们把控制台输出的日志写入到本地。这个功能说简单就简单&#xff0c;说复杂其实还挺复杂。 为什么这么说呢&#xff0c;首先文件写入本地确实简单&#xff0c;但是如果你要实现一下功能就没那么简单了。 1.把每行日志按照指…

log4net多进程丢失日志的解决方法

首先为什么会有多进程同时记录日志到同一个文件夹同一个文件里呢&#xff0c;每个项目肯定有每个项目的特殊性&#xff0c;我这里.net的BS项目&#xff0c;主要是因为在IIS里&#xff0c;应用程序池&#xff0c;最大工作进程设置成2&#xff0c;就会出现2个w3p什么的进程同时运…

C# log4net 日志输出超详细

思路&#xff1a; 1.安装插件&#xff1a;安装log4net 2.使用配置&#xff1a;添加log4net配置信息 3.输出日志文件格式&#xff1a;添加日志配置 4.AssemblyInfo.cs中配置 第一步&#xff1a;安装log4net 第二步&#xff1a;在app.config添加log4net配置 新增log4net.config…

.Net Core3.1 集成Log4net

准备 第一步&#xff1a;nuget 引用 Microsoft.Extensions.Logging.Log4Net.AspNetCore 第二步&#xff1a;在项目中添加log4net.config的配置文件(配置文件在文末) 第三步&#xff1a;在项目中注册使用log4net 方法一&#xff1a;在Program.cs中注册&#xff0c;找到 Prog…

C#上位机开发(十三)—— 使用Log4net添加日志记录功能

一、Log4net 官方网站:https://logging.apache.org/log4net/。 下载二进制dll库: 包中提供了针对各个版本的dll库: 二、使用日志库 1. 添加库 复制对应的库文件到项目中: 2. 配置log4net 2.1. 创建配置文件 添加后修改该文件设置:

unity log4net

log4.et.confog.xml <?xml version"1.0" encoding"utf-8" ?><log4net> <appender name"Error" type"log4net.Appender.RollingFileAppender"> <lockingModel type"log4net.Appender.FileAppenderMinimal…

C#-Winform之log4net使用详细记录

一、作用 提供一个记录日志的框架&#xff0c;可以将日志信息记录到文件、控制台、Windows事件日志和数据库&#xff08;MSSQL、Acess、Oracle、DB2和SQLite等&#xff09;。 二、操作步骤 1.在项目中添加对log4net.dll的引用&#xff08;通过NuGet可以直接安装&#xff09; …

log4net在linux中不生成日志,log4net使用记录

1、在程序中引用log4net.dll 2、添加-新建配置文件Log4Net.config&#xff0c;并在文件属性中“复制到输出目录”选中“始终复制”&#xff0c;文件内容如下&#xff1a; 3、在AssemblyInfo.cs中添加代码&#xff0c;用于调用Log4Net.config&#xff1a; [assembly: log4net.Co…

log4net在.Net Core使用

log4net的使用&#xff0c;可以把日志信息输出到各种不同终端&#xff08;文本文件、数据库、windows日志等&#xff09;&#xff0c;实现过程主要是各种输出方式的配置文件怎样配置&#xff1a; 1.安装log4net包 如果需要输出到数据库&#xff0c;相应的引入包 注意&#xf…

C#log4net的使用教程

1.我们在工具层使用NuGet添加log4net引用包 2.添加LogHelper帮助类 public class LogHelper{private static ILog _lognet LogManager.GetLogger(typeof(LogHelper));public static void WriterErrorLog(string logMessage) {_lognet.Error(logMessage);}public static void W…

C# log4net日志库的简单使用

C# log4net日志库的简单使用 一、简述 记--log4net日志开源库的简单使用&#xff1a;控制日志文件大小&#xff0c;日志文件个数&#xff0c;滚动式覆盖&#xff0c;自由控制日志打印等级 例子打包&#xff1a;外链:https://wwa.lanzoui.com/b0c9qvfqf 密码:67y7 二、下载log…