mysql慢查询工具explain

explain:mysql分析优化工具

explain能解释mysql如何处理SQL语句,表的加载顺序,表是如何连接,以及索引使用情况。是SQL优化的重要工具

在select语句之前增加 explain 关键字,MySQL 会在查询上设置一个标记,执行查询会返回执行计划的信息,而不是执行这条SQL

如果 from 中包含子查询,仍会执行该子查询,将结果放入临时表中。

Explain extended看起来和正常的explain行为一样,但它会告诉服务器"逆向编译"执行计划为一个select语句。可以通过紧接其后运行showwarnings看到这个生成的语句。这个语句直接来自执行计划,而不是原SQL语句,到这点上已经变成一个数据结构。大部分场景下,它都是优化过的,跟原语句不相同,可以学习查询优化器到底是如何转化语句的

Explain partitions会显示查询将访问的分区,如果查询是基于分区表的话。一般认为增加explain时,MySQL语句不会执行查询,这是错误的。如果查询在from子句中包括子查询,那么MySQL实际上是会执行子查询,将其结果放在一个临时表中,然后完成外层查询优化。

原表结构

原表数据

执行查询语句 查找price=30的所有数据

sql 复制代码
SELECT * FROM test_db WHERE price = 30

可以看到只有一条数据

用explain语句来分析下本次查询是否命中索引

sql 复制代码
EXPLAIN SELECT * FROM test_db WHERE price = 30;

可以看到出现了一行数据

字段含义

id

id表示执行select查询语句的序号,它是sql执行的顺序的标识,sql按照id从大到小执行,id相同的为一组,从上到下执行。例如使用联表和多表查询的时候,sql的查询顺序

id相同情况:

sql 复制代码
EXPLAIN SELECT * FROM user_db WHERE id in (SELECT id FROM test_db WHERE id = 1);

则这里的多表查询,id相同,先执行user_db,后执行test_db

id不同情况:

sql 复制代码
EXPLAIN SELECT * FROM user_db WHERE id = (SELECT id FROM test_db WHERE id = 1);

id大的先执行,所以先执行user_db的查询,后执行test_db的查询

select_type

select_type表示查询的类型,也就是对应的是简单查询还是复杂查询

simple

简单查询,不包括复杂的语句,多表查询也可以可以有JOIN连接

简单查询

sql 复制代码
select * from user_db where user_name = "test_t";

多表查询用join

sql 复制代码
SELECT * FROM user_db JOIN  test_db on user_db.id = test_db.id
sql 复制代码
EXPLAIN SELECT * FROM user_db JOIN  test_db on user_db.id = test_db.id;

可以看到select_type都是simple

primary

包含多个查询语句

子查询(in):

sql 复制代码
EXPLAIN SELECT * FROM user_db WHERE id in (SELECT price FROM test_db WHERE name = "3") or id =3;

这里primary指的是最左边执行查询的表

union

sql 复制代码
EXPLAIN SELECT id FROM user_db WHERE id =3 union SELECT id FROM test_db WHERE id = 3;

使用union查询需保证字段一致和结构一致

primary指的是在最左边执行查询的表

其余的均标记为union

union
sql 复制代码
EXPLAIN SELECT id FROM user_db WHERE id =3 union SELECT id FROM test_db WHERE id = 3;

使用union查询需保证字段一致和结构一致

其余的均标记为union

UNION RESULT

UNION使用临时表进行去重,标记临时表的查询为UNION RESULT

SUBQUERY

在**「select或者where中包含的子查询」**会被表示为SUBQUERY类型

sql 复制代码
EXPLAIN SELECT * FROM user_db WHERE id in (SELECT price FROM test_db WHERE name = "3") or id =3;
DERIVED

「DERIVED表示的是派生表或者衍生表的意思,在from包含的子查询中会被表示为DERIVED类型」,Mysql会递归执行这些子查询,并且把结果放在临时表中。

在8.0之后的版本很难出现这类情况

sql 复制代码
EXPLAIN SELECT * FROM (SELECT * FROM test_db where id>1) a where a.price=1;
DEPENDENT SUBQUERY(依赖性子查询)

只要出现了DEPENDENT 关键字,就表示是依赖性查询,依赖指的是依赖于主查询。该字段出现表示是出现了相关子查询,意思是子查询里面的表要依赖于主查询中的数据。

sql 复制代码
EXPLAIN SELECT id FROM user_db WHERE id =(SELECT id FROM test_db WHERE id=user_db.id);
UNCACHEABLE UNION(未被缓存的查询)

该字段出现表示查询出来的结果不能放到缓存中。出现于子查询里面又有一个union查询,但是union后面的那张表(goods_db)和主查询中的表(test_db)没有联系的情况。

sql 复制代码
EXPLAIN SELECT id FROM test_db WHERE id =(SELECT id FROM user_db WHERE id=test_db.id union select id from goods_db where user_id = 30);
DEPENDENT UNION(依赖性联合查询)

表示子查询里面出现了union查询,但是union后面的那张表和主查询有联系。

sql 复制代码
EXPLAIN SELECT id FROM test_db WHERE id =(SELECT id FROM goods_db WHERE id=30 union select id from user_db where id = test_db.id);

UNCACHEABLE SUBQUERY(未被缓存的子查询)

表示子查询里面出现了子查询,但是子查询的表和主查询无联系。

sql 复制代码
EXPLAIN SELECT id FROM test_db WHERE id =(SELECT id FROM goods_db WHERE id=30 union select id from user_db where id = test_db.id);
table

这一列表示 explain 的一行正在访问哪个表。

如果出现了 <derived 数字>,表示是用到了衍生表,数字是该表出现的顺序

type

它显示了该select SQL使用了何种方式进行查询

性能从好到差依次是: system、const、eq_ref、ref、range、index、all

system:表中只有一条数据

const:从表中通过常量只查询出一条数据,并且这条数据是通过主键索引或者唯一索引来查询出来的。

sql 复制代码
EXPLAIN SELECT * FROM test_db where id=30;

eq_ref:唯一性索引,对于要查询的字段,只返回匹配唯一的一行数据,有且只能有一个,在唯一索引和主键索引上

sql 复制代码
EXPLAIN SELECT id FROM test_db WHERE id =(SELECT id FROM goods_db WHERE id=30 union select id from user_db where id = test_db.id);

这里user_db用到了唯一性索引,id为主键索引而且自增不唯一

ref

非唯一性索引,对于索引的查询,可以返回0个或多个

range

执行索引查询的范围,使用between、>、<、in

index

使用index表示从当前索引树(B+树)来进行查询

All

表示全表扫描

Possible_keys

这一列显示理论上应该可能用到的索引有哪些,这个数量最好和select 后面查询的字段数量是一致的。如果使用了索引,但是没有出现在该列中,则说明该SQL使用的是覆盖索引。如果为null,表示没有用到索引。

key

实际用到的索引

key_len

索引长度,单位字节

为了可以节约空间,索引长度小点更好

ref

表示用到了哪个表的哪个字段

sql 复制代码
EXPLAIN SELECT id FROM test_db WHERE id =(SELECT id FROM goods_db WHERE id=30 union select id from user_db where id = test_db.id);

可以看到第三张表user_db用到了test_db这张表

第二张表goods_db为const,即where的查询条件为常量

rows

通过索引查到的数据个数,即通过索引查询找到的数据行数

extra

其它的重要字段

复制代码
Using filesort

查询过程中需重新查询一次,查询id之后还的再次查询price以根据price来排序

sql 复制代码
EXPLAIN SELECT id FROM test_db order by price;
复制代码
Using temporary

开辟了临时表,性能损耗大,常见于group by语句

sql 复制代码
EXPLAIN SELECT max(price) FROM test_db group by price;

using index

表示使用到了覆盖索引,不用进行回表查询

sql 复制代码
EXPLAIN SELECT id FROM test_db WHERE id =(SELECT id FROM goods_db WHERE id=30 union select id from user_db where id = test_db.id);

其中第二、三张表都使用了覆盖索引

using where

需回表查询

相关推荐
APItesterCris1 小时前
除了 Python,还有哪些语言可以调用淘宝 API?
大数据·开发语言·数据库·python
AI大模型训练家2 小时前
2025Java面试题超详细整理《微服务篇》
android·数据库·redis·sql·微服务·架构·wpf
Gauss松鼠会3 小时前
GaussDB安全配置建议
大数据·网络·数据库·安全·gaussdb
扎量丙不要犟3 小时前
excel电子表(或csv)中如何合并两个工作表,超过1,048,576行
数据库·excel·csv·hpctb
勇敢一点♂5 小时前
canal-python的安装与入门
数据库·python
何似在人间5756 小时前
MySQL锁类型(详解)
数据库·sql·mysql
逆天小北鼻7 小时前
oracle 基础语法复习记录
数据库·学习·oracle
想做富婆7 小时前
oracle: 表分区>>范围分区,列表分区,散列分区/哈希分区,间隔分区,参考分区,组合分区,子分区/复合分区/组合分区
数据库·oracle·表分区
小梁不秃捏7 小时前
数据库技术基础
数据库·后端