侧边栏壁纸
博主昵称
流苏小筑

步伐虽小,密而不止

EXPLAIN:Extra字段详解

2024年01月23日 14阅读 0评论 0点赞

EXPLAIN:Extra字段详解

顾名思义, Extra 列是用来说明一些额外信息的,包含不适合在其他列中显示但十分重要的额外信息。 我们可以通过这些额外信息来 更准确的理解MySQL到底将如何执行给定的查询语句。MySQL提供的额外信息 有好几十个,我们就不一个一个介绍了,所以我们只挑选比较重要的额外信息介绍给大家。

1. No tables used

当查询语句没有 FROM 子句时将会提示该额外信息,比如:
m4f6x62t.png

2. Impossible WHERE

当查询语句的 WHERE 子句永远为 FALSE 时将会提示该额外信息

EXPLAIN SELECT * FROM s1 WHERE 1 != 1;

m4f6xp8y.png

3. Using where

  • 当我们使用全表扫描来执行对某个表的查询,并且该语句的WHEE子句中有针对该表的搜索条件时,在`Extra列中会提示上述额外信息。比如下边这个查询:

    EXPLAIN SELECT * FROM s1 WHERE common_field = 'a';

    m4f6ygyq.png

  • 当使用索引访问米执行对某个表的查询,并且该语句的where子句中有除了该索引包含的列之外的其他搜索条件时,在Extra列中也会提示上述额外信息。

    EXPLAIN SELECT * FROM s1 WHERE key1 = 'a' AND common_field = 'a';

    m4f6yvrr.png
    虽然使用了key1索引,但是还是用了commmon_field作为搜索条件。

4. No matching min/max row

当查询列表处有 MIN 或者 MAX 聚合函数,但是并没有符合WHERE 子句中的搜索条件的记录时。

EXPLAIN SELECT MIN(key1) FROM s1 WHERE key1 = 'abcdefg';

m4f6zmmp.png
m4f6zqlg.png

5. Using index

当我们的查询列表以及搜索条件中只包含属于某个索引的列,也就是在可以使用覆盖索引的情况 下,在 Extra 列将会提示该额外信息。比方说下边这个查询中只需要用到 idx_key1 而不需要回表操作:

EXPLAIN SELECT key1 FROM s1 WHERE key1 = 'a';

m4f72aft.png

6. Using index condition (索引条件下推)

有些搜索条件中虽然出现了索引列,但却不能使用到索引,比如下边这个查询:

explain SELECT * FROM s1 WHERE key1 > 'z' AND key1 LIKE '%a';

m4f72pto.png

7. Using join buffer (Block Nested Loop)

在连接查询执行过程中,当被驱动表不能有效的利用索引加快访问速度,MySQL一般会为其分配一块名叫 join buffer 的内存块来加快查询速度,也就是我们所讲的基于块的嵌套循环算法

EXPLAIN SELECT * FROM s1 INNER JOIN s2 ON s1.common_field = s2.common_field;

m4f739ay.png

8. Not exists

当我们使用左(外)连接,如果where子句中包含要求被驱动表的某个列等于NULL值的搜索条件,而且那个列又是不允许存储NULL值的,那么在该表的执行计划的Extra列就会提示Not exists额外信息

EXPLAIN SELECT * FROM s1 LEFT JOIN s2 ON s1.key1 = s2.key1 WHERE s2.id IS NULL;

m4f73uv5.png

9. Using intersect(...) 、 Using union(...) 和 Using sort_union(...)

如果执行计划的 Extra 列出现了 Using intersect(...) 提示,说明准备使用 并的方式执行查询,括号中Intersect 索引合 ... 表示需要进行索引合并的索引名称;
如果出现 Using union(...) 提示,说明准备使用 Union 索引合并的方式执行查询。
如果出现 Using sort_union(...) 提示,说明准备使用 Sort-Union 索引合并的方式执行查询。
m4f7474q.png

10. Zero limit

当我们的 LIMIT 子句的参数为0时,表示压根儿不打算从表中读取任何记录,将会提示该额外信息

EXPLAIN SELECT * FROM s1 LIMIT 0;

m4f74n22.png

11. Using filesort

文件排序:
很多情况下排序操作无法使用到索引,只能在内存中(记录较少的时候)或者磁盘中(记录较多的时候)进行排序,MySQL把这种在内存中或者磁盘上进行排序的方式统称为文件排序。

#索引列排序
EXPLAIN SELECT * FROM s1 ORDER BY key1 LIMIT 10;

#普通列排序
EXPLAIN SELECT * FROM s1 ORDER BY common_field LIMIT 10;

m4f759jr.png

12. Using temporary(使用临时表)

在许多查询的执行过程中,MySQL可能会借助临时表来完成一些功能,比如去重、排序之类的,比如我们
在执行许多包含DISTINCT'、GROUP BYUNION`等子句的查询过程中,如果不能有效利用索引来完成
查询,MySQL很有可能寻求通过建立内部的临时表来执行查询。如果查询中使用到了内部的临时表,在执行
计划的Extra列将会显示`Using temporary'提示

EXPLAIN SELECT DISTINCT common_field FROM s1;

m4f776w6.png

同样,分组也需要使用临时表

EXPLAIN SELECT common_field,COUNT(*) AS amount FROM s1 GROUP BY common_field;

m4f77qmp.png

但是注意,如果是索引列,则不需要临时表

EXPLAIN SELECT key1,COUNT(*) AS amount FROM s1 GROUP BY key1;

m4f785cu.png
执行计划中出现Using temporary并不是一个好的效率,因为建立与维护临时表要付出很大成本的,所以
我们~最好能使用索引来替代掉使用临时表。比如扫描指定的索引idx key1即可。


● EXPLAIN不考虑各种Cache
● EXPLAIN不能显示MySQL在执行查询时所作的优化工作
● EXPLAIN不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况
● 部分统计信息是估算的,并非精确值

0

—— 评论区 ——

昵称
邮箱
网址
取消