mysql的explain

每一行都是一个执行步骤

id:执行顺序

select type:查询语句的操作类型

table:表

parititions:表分区

type:查询所用的访问类型

possible-keys:可能用到的索引

key:实际查询用到的索引

key-len:所使用的索引的长度(主要是看联合索引)

ref:使用索引时,与索引进行等值匹配的列或者常量

rows:预计扫描的行数(索引行数或者表记录行数)

filtered:表示符合查询条件的数据百分比

extra:额外信息

id列

id序号相同:顺序是从上往下

id序号不同,顺序是从大到小

id列为null,最后执行

table

表名

derived:派生表

派生表(derived table)在 MySQL 中主要是在服务器层面(server layer)管理的,而不是在存储引擎层面。

存储位置

服务器层面:派生表由 MySQL 服务器层管理。服务器层负责解析 SQL 查询、优化查询计划、生成派生表并使用它们。具体来说,服务器层负责将子查询的结果存储在临时表中。

存储引擎层面:存储引擎负责物理存储数据。在派生表的情况下,如果派生表的结果较大,需要写入磁盘,那么存储引擎(如 InnoDB 或 MyISAM)会参与存储这些临时数据。但是,派生表本身的管理和生命周期由服务器层负责。

生命周期

临时性:派生表在查询执行期间临时存在,一旦查询结束,派生表就被销毁。这意味着它们的生命周期仅限于生成它们的查询上下文。

销毁:查询执行完毕后,派生表及其数据会被立即销毁,不会保留在内存或磁盘上。

生成过程

遍历生成:派生表的生成确实需要遍历子查询中的相关表。例如,如果子查询中涉及到 users 表,MySQL 会遍历 users 表以生成派生表的结果集。如果条件可以使用索引来获得派生表,那么就会使用索引。

例子
csharp 复制代码
+----+-------------+--------------+-------+---------------+---------+---------+------+--------+-----------------------------+
| id | select_type | table        | type  | possible_keys | key     | key_len | ref  | rows   | Extra                       |
+----+-------------+--------------+-------+---------------+---------+---------+------+--------+-----------------------------+
|  1 | PRIMARY     | <derived2>   | ALL   | NULL          | NULL    | NULL    | NULL | 2      |                             |
|  2 | DERIVED     | users        | range | age           | age     | 4       | NULL | 2      | Using where; Using filesort |
+----+-------------+--------------+-------+---------------+---------+---------+------+--------+-----------------------------+

id2的select_type为derived代表生成users的派生表,id为1的table为derived2代表使用id为2的派生表来遍历。

select type:查询类型

用来区分普通查询,子查询,联合查询(复杂查询)。

  • SIMPLE:简单的SELECT查询,不包含子查询或UNION。
  • PRIMARY:最外层的SELECT查询。如果查询中包含子查询或联合查询,则最外层的查询是PRIMARY类型。
  • UNION:UNION中的第二个或后续的SELECT查询。
  • DEPENDENT UNION:UNION中的第二个或后续的SELECT查询,依赖于外部查询。
  • UNION RESULT:用于表示UNION的结果集。
  • SUBQUERY:子查询中的第一个SELECT。
  • DEPENDENT SUBQUERY:子查询中的第一个SELECT,依赖于外部查询。
  • DERIVED:派生表的SELECT(例如,在FROM子句中使用的子查询)。

simple:不包含union和子查询,那么就是简单查询

连接查询也会被标记为simple

primary:复杂查询中的最外层的查询,通常union和子查询id为1的查询

subquery:子查询,不依赖于外部

csharp 复制代码
explain select *,(select productName form products where id=1) from user.

dependent subquery:子查询,依赖于外部

例子:

csharp 复制代码
explain select *,(select productName from products where products.id=user.product) from user;

derived:派生表,from中子查询

csharp 复制代码
explain select * from (select * from user where user_id>=1);

派生表合并优化的基本思想是将派生表的查询嵌入到主查询中,直接生成一个更复杂的查询,从而避免创建临时表。

当派生表合并优化生效时,使用 EXPLAIN 来检查查询的执行计划时,不会显示 derived 类型的查询,而是会显示 simple 类型的查询。

union

csharp 复制代码
select * from (
select * from user where id<3
union
select * from user where length(name)<6
union
sleect * from user where id>300
);

from子查询,第一个select会作为derived的派生表,其余都是union,然后最外层的是primary。

如果是union all 会生成一个临时表去重。

dependent union

possible_key:可能使用的索引

key:实际使用的索引

type:查询使用的访问类型

system:表只有一条数据(innodb没有)

const:就是条件为主键或者唯一索引的常量等于

eq_ref:使用两个表的主键或者唯一索引连接的select,使用主键或者唯一索引来访问

ref:ref就是使用非唯一索引进行查找或者使用非唯一索引连接的表,使用非唯一索引进行访问

range:有索引的范围查找

index:表示查询使用了覆盖索引,可以直接从索引中获取所需的数据,无需回表

all:全表扫描

ken_len:使用的索引的最大长度

主要看,覆盖索引使用了多长

CHAR(n):固定长度字符串,占据 n 字节的存储空间,不管实际存储的字符数是多少。

int:4字节

varchar:如果是utf-8,那就是3n+2,2用来存储实际varchar的字数

如果没有not null,那么会有一字节存储是否为null。

ref:显示使用的非唯一索引名称

rows:扫描的行数

filtered:符合查询条件的数据的百分比

Extra

using index:覆盖索引

using where:不使用索引

using index condition:用索引找到后回表

using filesort:在内存或者在磁盘中排序:需要添加索引从而直接取出排序后的行

相关推荐
一 乐2 小时前
民宿|基于java的民宿推荐系统(源码+数据库+文档)
java·前端·数据库·vue.js·论文·源码
鹏码纵横2 小时前
已解决:java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 异常的正确解决方法,亲测有效!!!
java·python·mysql
美林数据Tempodata4 小时前
大模型驱动数据分析革新:美林数据智能问数解决方案破局传统 BI 痛点
数据库·人工智能·数据分析·大模型·智能问数
野槐4 小时前
node.js连接mysql写接口(一)
数据库·mysql
Zzzone6834 小时前
PostgreSQL日常维护
数据库·postgresql
chxii4 小时前
1.13使用 Node.js 操作 SQLite
数据库·sqlite·node.js
冰刀画的圈4 小时前
修改Oracle编码
数据库·oracle
这个胖子不太裤5 小时前
Django(自用)
数据库·django·sqlite
麻辣清汤5 小时前
MySQL 索引类型及其必要性与优点
数据库·mysql
2501_915374356 小时前
Neo4j 图数据库安装教程(2024最新版)—— Windows / Linux / macOS 全平台指南
数据库·windows·neo4j