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

需回表查询

相关推荐
小云数据库服务专线19 分钟前
GaussDB 数据库设计规范
数据库·设计规范·gaussdb
我来整一篇1 小时前
[mssql] 分析SQL Server中执行效率较低的SQL语句
数据库·sql·sqlserver
元亓亓亓1 小时前
Redis--day1--初识Redis
数据库·redis·缓存
每天敲200行代码1 小时前
Redis 初识Redis
数据库·redis·github
波波玩转AI1 小时前
MyBatis核心
数据库·mybatis
会编程的林俊杰2 小时前
Redis事务机制
数据库·redis·缓存
叁沐2 小时前
MySQL 24 MySQL是怎么保证主备一致的?
mysql
阿蒙Amon3 小时前
详解Python标准库之互联网数据处理
网络·数据库·python
77qqqiqi4 小时前
解决忘记修改配置密码而无法连接nacos的问题
java·数据库·docker·微服务
ALLSectorSorft4 小时前
相亲小程序用户注册与登录系统模块搭建
java·大数据·服务器·数据库·python