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

需回表查询

相关推荐
JAVA面经实录91729 分钟前
Hibernate面试题库
数据库·oracle·hibernate
2301_7736436244 分钟前
华为云存储实验
网络·mysql·华为云
迷枫7121 小时前
DM8 目录结构与常用排查入口梳理
服务器·数据库
Mr.Daozhi2 小时前
RAG 进阶实战:跑通 Demo 后我连续翻了 6 次车,逐一修复才真正可用(含 Gradio Web 版)
前端·数据库·langchain·大模型·gradio·rag·科研工具
小程故事多_802 小时前
Claude Code自定义workflow skills用法
数据库·人工智能·智能体
大鹏说大话2 小时前
SQL 排序与分组实战:解决“分组后取最新数据“
android·java·数据库
quan26312 小时前
20260529,日常开发-数据库主从问题
java·mysql·主从·延迟
夏贰四3 小时前
数据建模工具如何筑牢数据根基?数据建模工具怎样落实标准体系?
数据库·数学建模·数据建模工具
程序猿阿伟4 小时前
《一套完整方法论:搞定图形应用的Docker镜像优化》
数据库·docker·容器
二等饼干~za8986684 小时前
geo优化源码开发搭建技术分享
大数据·网络·数据库·人工智能·音视频