EXPLAIN使用介绍

本文详细介绍MySQL中的EXPLAIN命令,包括其使用方法及各属性的作用。通过实例解析id、select_type等字段含义,并给出优化建议。

目录

测试数据准备

建表

初始化数据 

EXPLAIN 如何使用

属性分析

id

select_type

table列

type

possible_key、key

key_len

ref

rows

filtered

Extra


EXPLAIN 语句提供了有关 MySQL 如何执行 SQL 的相关信息,是我们必须掌握的SQL优化神器。

官网对EXPLAIN的解释:https://dev.mysql.com/doc/refman/5.7/en/explain-output.html

测试数据准备

建表

DROP TABLE IF EXISTS course;
CREATE TABLE `course`
(
`cid` int NOT NULL AUTO_INCREMENT COMMENT '课程编号',
`tid` int DEFAULT NULL COMMENT '教师编号',
`cname` varchar(20) DEFAULT NULL COMMENT '课程名称',
PRIMARY KEY (cid)
) COMMENT = '课程信息表';

DROP TABLE IF EXISTS teacher;
CREATE TABLE `teacher`
(
`tid` int NOT NULL AUTO_INCREMENT COMMENT '教师编号',
`tname` varchar(20) DEFAULT NULL COMMENT '教师名字',
PRIMARY KEY (tid)
) COMMENT = '教师信息表';

DROP TABLE IF EXISTS teacher_detail;
CREATE TABLE `teacher_detail`
(
`tdid` int NOT NULL AUTO_INCREMENT COMMENT '详情编号',
`tid` int DEFAULT NULL COMMENT '教师编号',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号',
PRIMARY KEY (tdid),
UNIQUE KEY (tid),
KEY(phone)
) COMMENT = '教师详细信息表';

初始化数据 

delimiter $$
DROP PROCEDURE IF EXISTS init;
create procedure init()
begin
declare i int;
declare id1 int;
declare id2 int;
declare id3 int;
declare id4 int;
declare id5 int;
set i = 1;

while i < 5000 do
set id1 = i;
set id2 = i + 4;
set id3 = i + 5;
set id4 = i + 6;
set id5 = i + 9;

INSERT INTO `teacher`
VALUES (id1, CONCAT('老师', id1)),
(id2, CONCAT('教师', id2)),
(id3, CONCAT('老师', id3)),
(id4, CONCAT('老师', id4)),
(id5, CONCAT('老师', id5));

INSERT INTO `course`
VALUES (id1, id1,'英语'),
(id2, id2,'数学'),
(id3, id3,'物理'),
(id4, id4,'化学'),
(id5, id5,'语文');

INSERT INTO `teacher_detail`
VALUES (id1,id1, (13800000000 + id1)),
(id2,id2, (13800000000 + id2)),
(id3,id3, (13800000000 + id3)),
(id4,id4, (13800000000 + id4)),
(id5,id5, (13800000000 + id1));

set i = i + 10;
end while;
end
$$

call init();

EXPLAIN 如何使用

EXPLAIN 是MySQL 提供的原生关键字,使用非常简单,只需要在目标 SQL 前加上 EXPLAIN 再执行即可。

例如:

EXPLAIN SELECT * FROM teacher;

 

下面就依次分析返回结果中的属性。

属性分析

id

id字段体现了SQL的执行顺序。id相同时,先执行排在上面的。

EXPLAIN SELECT * FROM course c INNER JOIN teacher t ON c.tid = t.tid;

id不同时,先执行id较大的。

EXPLAIN SELECT * FROM course c WHERE c.tid = (SELECT td.tid FROM teacher_detail td WHERE td.phone = '13800000040');

select_type

select_type即查询类型,这里只介绍一些常见的类型。

  • SIMPLE:简单查询,不包含子查询与联合查询UNION。
  • PRIMARY:包含子查询SQL中的主查询,即复杂查询中最外层的 select
  • SUBQUERY:包含在 select 中的子查询(不在 from 子句中)
  • DERIVED:衍生查询,表示在得到最终查询结果之前会用到临时表。
  • UNION:用到了联合查询。
  • UNION RESULT:主要是显示哪些表之间存在 UNION 查询。<union2,3>代表 id=2 和 id=3 的查询存在 UNION。

例:

EXPLAIN SELECT cr.cname FROM ( SELECT * FROM course WHERE tid = 2 UNION SELECT * FROM course WHERE tid = 3 ) cr;

table列

这一列表示 explain 的一行正在访问哪个表。
当 from 子句中有子查询时,table列是 <derivenN> 格式,表示当前查询依赖 id=N 的查询,于是先执行 id=N的查 询
当有 union 时,UNION RESULT 的 table 列的值为<union1,2>,1和2表示参与 union 的 select 行id。

type

type代表连接类型,是执行计划中最为重要的属性之一,下面列举最常见的几种type。

效率依次从高到低:system > const > eq_ref > ref > range > index ≈ all

system:表中只有一行记录(等于系统表),const类型的特例。

const:使用主键或唯一索引进行比较。

eq_ref:通常出现在多表的 JOIN 查询,表示对于前表的每一个结果,都只能匹配到后表的一行结果(即一一对应,且后一张表对应字段索引一般是唯一索引)。一般是唯一性索引的查询(UNIQUE 或 PRIMARY KEY)。

例:

EXPLAIN SELECT * FROM course c INNER JOIN teacher t ON c.tid = t.tid;

如上:针对于course的某一条记录,关联时在teacher只有一条记录与之对应。

ref:查询用到了非唯一性索引,或者关联操作只使用了索引的最左前缀。

例:

EXPLAIN SELECT td.tid FROM teacher_detail td WHERE td.phone = '13800000040';



range:使用索引范围扫描。

例:

EXPLAIN SELECT * FROM teacher WHERE tid < 1000;



index:全索引扫描。一般出现在索引条件区分度不高的场景下,未必比全表扫描快。

例:


all:全表扫描。

总结:一般来说,需要保证查询至少达到 range 级别,最好能达到 ref。index、与all 都是需要优化的。

possible_key、key

可能用到的索引和实际用到的索引。

possible_key 可以有一个或者多个,可能用到的索引不代表一定会用到。

反过来如果possible_key 为 null,key 就一定为空吗?

EXPLAIN SELECT phone FROM teacher_detail WHERE phone LIKE '%3800000040%';

当查询条件无法命中索引,但查询结果为索引字段时,就会出现这种情况,这里相对于用到了覆盖索引。

key_len

索引的长度(使用的字节数)。跟索引字段的类型、长度有关。

key_len计算规则如下:

ref

这一列显示了在索引列中,查找值所用到的列或常量,常见的有const(常量)、字段名、NULL。

rows

MySQL 认为扫描多少行才能返回请求的数据,是一个预估值。一般来说行数越少越好。

filtered

这个字段表示存储引擎返回的数据在 server 层过滤后,剩下多少满足查询的记录数量的比例,它是一个百分比。

例如全表扫描后,只有一条记录满足查询条件,那么 filtered 的值就会比较低。

EXPLAIN SELECT * FROM course WHERE tid = 100;


Extra

执行计划给出的额外的信息说明。

Using index:查询使用了覆盖索引,不需要回表。

Using where:两种情况:

  1. 查询使用了 where 过滤,但没有用到索引;
  2. 有索引的过滤,且不需要回表。

Using index condition:查询用到索引且需要回表。这里说的回表有可能是为了拿数据,有可能是为了进一步过滤(索引下推)。

Using filesort:不能使用索引来排序,用到了临时文件排序。

Using temporary:用到了临时表(内存或磁盘)。例如:

  1. distinct 非索引列;
  2. group by 非索引列;
  3. 使用 join 的时候,group by 非驱动表的索引列同样会产生临时表。

转载地址:https://hujinyang.blog.youkuaiyun.com/article/details/103877385

<think>首先,用户的问题是关于MySQL的EXPLAIN使用步骤。我需要根据提供的引用来构建一个清晰、结构化的回答。引用内容提到了EXPLAIN的不同方面,包括基础使用、输出格式、额外选项如EXPLAIN EXTENDED和EXPLAIN ANALYZE,以及输出字段的含义。 关键点从引用中: - 引用[1]:EXPLAIN基础,使用默认文本格式,适合人类阅读;机器可读格式如XML、JSON、YAML。 - 引用[2]:EXPLAIN EXTENDED提供更多诊断信息,结合SHOW WARNINGS查看优化建议。 - 引用[3]:EXPLAIN ANALYZE(MySQL 8.0+)提供实际执行统计和树状结构。 - 引用[4]:详细解释了EXPLAIN输出字段的含义,如id、select_type、table、type等。 用户的问题具体是:"我想了解explain使用步骤 请问explain使用步骤说明"。所以,我需要列出使用EXPLAIN的步骤。 结构化回答: 1. **介绍EXPLAIN**:简要说明EXPLAIN的作用——分析查询执行计划。 2. **基本使用步骤**: - 如何在MySQL中使用EXPLAIN。 - 格式:EXPLAIN SELECT ... 或 EXPLAIN FORMAT=JSON SELECT ... 等。 3. **常见选项**: - EXPLAIN EXTENDED(结合SHOW WARNINGS)。 - EXPLAIN ANALYZE(MySQL 8.0+)。 4. **解读输出**:解释关键字段(基于引用[4]),如id、select_type、table、type、possible_keys、key、rows、Extra。 5. **输出格式**:提到文本格式和机器可读格式(XML、JSON、YAML)。 6. **示例**:提供一个简单的示例查询的EXPLAIN输出。 7. **结束**:自然地添加引用标识。 系统指令要求: - 行内数学表达式用$...$,但这里可能不涉及数学。 - 独立公式用$$...$$,但这里可能不需要。 - LaTeX语法正确:确保任何LaTeX正确。 - 使用中文回答:整个回答用中文。 - 生成相关问题:在最后添加相关问题。 - 引用标识:在回答末尾添加引用标识如[^1]。 回答结构: - 清晰、逐步介绍。 - 基于引用内容。 - 确保真实性。 大纲回答: 1. **开头**:解释EXPLAIN的作用。 2. **步骤1**:基本命令格式。 3. **步骤2**:运行EXPLAIN。 4. **步骤3**:解读输出字段。 5. **步骤4**:使用EXTENDED和ANALYZE选项。 6. **步骤5**:选择输出格式。 7. **示例**:给出一个简单示例。 8. **结尾**:总结。 9. **相关问题**:列出相关问题。 10. **引用**:添加引用标识。 相关问题生成: - 基于主题,如如何优化查询、常见问题等。 - 例如: 1. EXPLAIN输出中的type字段如何影响性能? 2. 如何使用EXPLAIN ANALYZE分析查询执行细节? 3. EXPLAIN EXTENDED能提供哪些额外信息? 最终回答格式: - 使用Markdown,如代码块显示SQL命令。 - 引用标识在引用内容的末尾。 </think>### MySQL EXPLAIN使用步骤说明 EXPLAIN是MySQL中分析SQL查询执行计划的关键工具,它能帮助开发者理解查询优化器的行为,识别性能瓶颈。以下是详细的使用步骤,基于MySQL官方文档和常见实践(如引用内容所述)。 #### 步骤1: 基本命令格式 在MySQL命令行或客户端中,直接在SELECT查询前添加`EXPLAIN`关键字即可。基本语法: ```sql EXPLAIN SELECT * FROM your_table WHERE your_condition; ``` - **说明**:这会返回查询的执行计划,默认以人类可读的文本格式输出(如引用[1]所述)。例如: ``` +----+-------------+-------------+-------+---------------+-----+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | rows | Extra | +----+-------------+-------------+-------+---------------+-----+---------+------+------+-------------+ | 1 | SIMPLE | your_table | ref | idx_column | idx_column | 4 | 10 | Using where | +----+-------------+-------------+-------+---------------+-----+---------+------+------+-------------+ ``` #### 步骤2: 运行EXPLAIN并查看输出 1. **执行命令**:在MySQL环境中运行你的EXPLAIN语句。 2. **解读关键字段**(基于引用[4]的解释): - `id`: 查询序列号,表示操作顺序。 - `select_type`: 查询类型(如SIMPLE、PRIMARY、SUBQUERY)。 - `table`: 涉及的表名。 - `type`: 连接类型(性能从优到劣:system → const → eq_ref → ref → range → index → all)。 - `possible_keys`: 可能使用的索引。 - `key`: 实际使用的索引。 - `rows`: 扫描的行数估计。 - `Extra`: 额外信息(如Using where)。 *重点关注`type`和`rows`字段,它们直接影响性能[^4]。* #### 步骤3: 使用高级选项(可选) - **EXPLAIN EXTENDED**: - 提供更详细的诊断信息。 - 语法:`EXPLAIN EXTENDED SELECT ...;` - 运行后,使用`SHOW WARNINGS;`查看优化建议(如MySQL对查询重写的提示)。 *例如,在复杂查询中诊断索引使用问题[^2]。* - **EXPLAIN ANALYZE**(MySQL 8.0+): - 提供实际执行统计和树状结构输出。 - 语法:`EXPLAIN ANALYZE SELECT ...;` - 输出包括实际耗时和资源消耗,适合深度性能分析。 *如引用[3]所述,它能直观显示查询流程[^3]。* #### 步骤4: 选择输出格式 - **默认文本格式**:适合快速阅读。 - **机器可读格式**:用于自动化分析(如XML、JSON、YAML)。 - 语法示例:`EXPLAIN FORMAT=JSON SELECT ...;` *这在将输出交给分析工具时非常有用[^1]。* #### 示例:完整使用流程 假设分析一个用户查询: ```sql EXPLAIN SELECT * FROM users WHERE name = 'john'; ``` 输出解读: - `type=ref`:表示使用了索引扫描。 - `rows=1`:估计扫描1行,效率较高。 - 如果性能不佳,可使用`EXPLAIN EXTENDED`后执行`SHOW WARNINGS;`查看优化提示。 #### 总结 EXPLAIN的核心步骤包括:运行基本命令→解读输出字段→可选扩展分析→选择格式优化可视化。定期使用它能显著提升查询性能[^4]。实践中,结合`EXPLAIN ANALYZE`(MySQL 8.0+)能获取更精确的执行细节[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值