explain 参数详解

explain 参数详解

ps:在MySQL中,SELECT语句的执行顺序如下:
FROM:指定数据源
JOIN:对数据源进行JOIN操作
WHERE:对JOIN后的数据进行筛选
GROUP BY:按照某个字段进行分组
HAVING:对分组后的数据进行筛选
SELECT:选择需要的列
DISTINCT:去重
ORDER BY:排序
LIMIT:限制返回的记录数

示例图


img

id


查询编号,表示查询中执行 SELECT 的序列号。对于简单的 SELECT 查询,这个值为 1,对于复杂查询,这个值会逐个递增。

select_type


SELECT 查询的类型,包括以下几种:

  • SIMPLE:简单的 SELECT 查询,不包含子查询或者 UNION。

  • PRIMARY:最外层的 SELECT 查询。

  • DERIVED:派生表的 SELECT 语句。

SELECT t1.idFROM table1 t1 JOIN(SELECT id FROM table2) t2 ON t1.id= t2.id;

在这个查询中,子查询 (SELECT id FROM table2) 返回一个结果集,该结果集会被存储在内存中或者磁盘上,然后被命名为 t2,作为派生表使用。这个派生表 t2 会被作为参数传递给外层查询,用来完成 JOIN 操作。因此这个查询的 select_type 是 DERIVED。

  • SUBQUERY

例如,在以下查询中,子查询返回每个用户的平均评分,外部查询则通过 HAVING 子句过滤出评分高于平均值的用户:

1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT user_id,AVG(rating)as avg_rating



FROM ratings



GROUPBY user_id



HAVINGAVG(rating)>(SELECTAVG(rating)FROM ratings)

在这种情况下,SELECT AVG(rating) FROM ratings 是一个子查询,它返回整个 ratings 表中所有评分的平均值。

  • UNION:表示查询中使用了UNION操作,并且从创建的派生表中检索数据。例如,以下查询将从两个表中检索最高薪水的员工,并使用UNION操作将结果组合在一起:
1
2
3
4
5
6
7
8
9
SELECT emp_id,MAX(salary)FROM employees GROUPBY emp_id



UNION



SELECT emp_id,MAX(salary)FROM contractors GROUPBY emp_id;

这个查询使用UNION将两个SELECT语句的结果组合在一起,并使用派生表来处理这些结果。

  • DEPENDENT UNION:表示在UNION查询中,子查询依赖于外部查询的结果集,也称作依赖联合查询。
1
2
3
4
5
6
7
8
9
SELECT id, name FROM table1



UNION



SELECT id, name FROM table2 WHERE id >(SELECTCOUNT(*)FROM table1)

这个查询将table1和table2的数据合并,并返回id和name列的值。在第二个SELECT子查询中,查询的结果依赖于第一个SELECT子查询的结果。

  • DEPENDENT SUBQUERY:表示一个依赖于外部查询的子查询。

当一个子查询中的表引用了外部查询的表时,就会产生依赖关系,即该子查询需要等待外部查询执行完毕才能开始执行,因此在执行过程中会使用到外部查询中的值。

下面是一个示例:

1
2
3
4
5
6
7
8
9
SELECT u.id, u.name



FROM users u



WHERE(SELECTAVG(amount)FROM orders o WHERE o.user_id= u.id)<(SELECT amount FROM orders o WHERE o.user_id= u.idORDERBY amount DESCLIMIT1)

这里包含两个子查询,其中第一个子查询 (SELECT AVG(amount) FROM orders o WHERE o.user_id = u.id) 用于计算该用户的平均订单金额,第二个子查询 (SELECT amount FROM orders o WHERE o.user_id = u.id ORDER BY amount DESC LIMIT 1) 用于查询该用户的订单中金额最大的一笔订单的金额。这两个子查询都是与外部查询有关联的,因此被标记为 DEPENDENT SUBQUERY。

  • UNCACHEABLE SUBQUERY:子查询不能被缓存,必须重新计算每个外部查询。

举个例子,假设我们有一个用户表(user)和一个订单表(order),我们想查询每个用户的订单数量。我们可以使用以下查询语句:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
SELECT



u.id,



u.name,



(



SELECTCOUNT(*)



FROMorder o



WHERE o.user_id= u.id



)AS order_count



FROMuser u;

这个查询中,子查询中的 COUNT(*) 函数需要根据 user_id 来计算每个用户的订单数量,而 user_id 来自外层查询的表。因为这个关联条件是动态计算的,因此 MySQL 不能对子查询进行缓存,因此该子查询就被标记为 UNCACHEABLE SUBQUERY。

  • UNCACHEABLE UNION:

表示该查询的 UNION 子句不可缓存,需要在每次执行时重新计算。这通常是因为 UNION 的两个 SELECT 语句中包含的字段类型不同,或者两个查询中的 ORDER BY 子句不同,导致 MySQL 无法缓存结果集,需要重新计算。

  • UNION RESULT:UNION 的结果。

table


显示此行查询的是哪个表。

partitions


匹配的分区列表,使用了分区表才有此列。

type


访问类型,包括以下几种:

  • ALL:Full Table Scan,表示全表扫描。

  • index:Full Index Scan,表示索引扫描。

  • range:表示索引范围扫描,常用于带有 between 和 in 的查询语句。

  • ref:表示使用非唯一索引或唯一索引的非唯一前缀查询,例如 where id = 10。

  • eq_ref:表示使用唯一索引查询,例如 where id = 10。

  • const、system:表示查询中只有一行或少数几行时使用的索引查询方式。

possible_keys


显示查询语句中可能使用到的索引。

key


实际使用的索引。

key_len


使用的索引长度。

ref


显示索引的哪一列被使用了,常见的是一个常量或者一个索引列的名字。

rows


预计查询返回的行数。

filtered


该查询条件所过滤的数据行百分比。

Extra


包含对查询的补充信息,通常包括以下几种:

  • Using index:表示该查询使用了覆盖索引,避免了回表查询,提高了查询效率。

  • Using where:表示该查询使用了WHERE条件语句。

  • Using temporary:表示MySQL需要使用临时表来处理查询,可能是由于GROUP BY和ORDER BY等操作导致的。

  • Using filesort:表示MySQL需要使用文件排序,可能是由于GROUP BY和ORDER BY等操作导致的。

表示查询中涉及到的排序操作无法使用索引完成,需要对结果集进行文件排序(Filesort)。文件排序操作需要先将需要排序的列从表中读取到内存中,然后进行排序操作,最后返回结果。

  • Using join buffer:表示MySQL需要使用连接缓存,加快查询效率。

  • Impossible where:表示WHERE条件无法满足,该查询不会返回任何数据。

  • Select tables optimized away:表示MySQL优化了查询,直接返回了结果,没有实际查询任何数据。


explain 参数详解
http://lanfunoe.site/2023/02/27/explain-参数详解/
作者
John Doe
发布于
2023年2月27日
许可协议