MySQL Explain详情

是什么

MySQL的Explain命令可以用于分析和优化SQL语句的性能。该命令可以模拟查询的执行计划,并提供有关如何执行查询的详细信息。
通过查看Explain输出,您可以确定是否使用了正确的索引,以及是否存在任何潜在的性能瓶颈。您可以使用这些信息来调整查询以提高其性能,例如添加索引或重写查询以使用更有效的操作顺序。

使用

在你书写的SQL语句加一个单词 - explain,然后将 explain + SQL执行后会出现一个表,这个表会告诉你MySQL优化器是怎样执行你的SQL的。下面我们来讲解一下表格里面的字段。

本文以示例为基础来讲解各个字段,示例表:
表1

CREATE TABLE `background_log` (
  `id` int(11)  NOT NULL AUTO_INCREMENT,
  `task` varchar(255)  NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `task_index` (`task`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

表2

CREATE TABLE `application` (
  `id` int(11)  NOT NULL AUTO_INCREMENT,
  `team_id` int(11) NOT NULL DEFAULT '0' COMMENT '组织id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

示例1

EXPLAIN SELECT * FROM `application` WHERE `team_id` = (SELECT `team_id` FROM `application` WHERE `id`= 202)

示例1

示例2

EXPLAIN SELECT id FROM (SELECT `id`, `team_id` FROM `application` WHERE `team_id` = 13) a;

示例2

示例3

EXPLAIN SELECT id FROM application;

示例3

示例4

EXPLAIN SELECT * FROM `background_log` WHERE `task`='拉取源代码完成.';

示例4

字段详解

id

查询中每个操作的唯一标识符,表示执行的顺序

  • id值越大,优先级越高,越先执行
  • id如果相同,可以认为是一组,从上往下顺序执行

如实例1所示

id为2的子查询更先执行,然后再执行id为1的主查询。

select_type

这一列返回查询类型,是简单查询还是复杂查询。简单查询为SIMPLE;复杂查询包括UNION,普通子查询和FROM子查询。具体的枚举类型包括:

  1. SIMPLE: 简单SELECT,不使用UNION或子查询等
  2. PRIMARY: 查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY
  3. UNION: UNION中的第二个或后面的SELECT语句
  4. DEPENDENT UNION: UNION中的第二个或后面的SELECT语句,取决于外面的查询
  5. UNION RESULT: UNION的结果
  6. SUBQUERY: 子查询中的第一个SELECT
  7. DEPENDENT SUBQUERY: 子查询中的第一个SELECT,取决于外面的查询
  8. DERIVED: 派生表的SELECT, FROM子句的子查询
  9. UNCACHEABLE SUBQUERY: 一个子查询的结果不能被缓存,必须重新评估外链接的第一行

如实例1所示

这个查询是普通子查询,第一行是主要查询,第二行是子查询。

普通子查询和FROM子查询的区别

普通子查询

普通子查询是嵌套在另一个查询的SELECT语句中,用于返回一个单一的值或多个值,通常与WHERE子句一起使用。例如:

SELECT column_name
FROM table_name
WHERE column_name = (SELECT column_name FROM another_table WHERE condition);
FROM子查询

FROM子查询是嵌套在另一个查询的FROM子句中,用于返回一个虚拟表,通常与JOIN子句一起使用。例如:

SELECT column_name
FROM table_name
JOIN (SELECT column_name FROM another_table WHERE condition) AS sub_table
ON table_name.column_name = sub_table.column_name;

在上述示例中,子查询(SELECT column_name FROM another_table WHERE condition)返回一个虚拟表,并将其用于JOIN子句中与table_name表进行连接。

table

显示这一行的数据是关于哪张表的,derivedx表示临时内存表。

如实例2所示

实例展示的是一个FROM子查询,FROM子查询的 derivedx 表示临时内存表。

partitions

该列显示的为分区表命中的分区情况。非分区表该字段为空(null)。

type

type字段表示MySQL在执行查询时使用的访问方法,也就是在查找匹配行时使用的算法。type字段是MySQL查询优化器选择索引的重要指标之一,它的值越优越快速,查询性能越好。以下性能由快到慢:

system

这是最高级别的查询类型,表示只有一行数据,因为这个查询只是对系统表中的一行数据进行操作,不需要扫描表。

const

表示使用主键或唯一索引进行匹配,查询结果只有一行数据。这是最快的查询类型之一。

eq_ref

表示连接时使用了唯一索引,常见于连接查询(Join),并且在查询结果集中使用索引的所有列的值都相等。

ref

使用非唯一索引或者唯一索引的非唯一性前缀

如实例4所示

查询使用普通索引,所以type 为 ref

range

表示使用索引扫描,只返回索引中匹配指定范围的行数据。这个范围可能是一个单独的值,或是一个范围。
一般使用了这些比较符:

  • =
  • <>
  • >
  • >=
  • <
  • <=
  • IS NULL
  • <=>
  • BETWEEN
  • IN()

index

表示进行全索引扫描,这种情况下MySQL将扫描整个索引来查找匹配的行,而不是扫描整个表。

如实例3所示

虽然查询使用了id这个索引,但是因为要对整个表查询,索引使用的是 index

all

表示进行全表扫描,这意味着MySQL将扫描整个表以查找匹配的行。这是最慢的查询类型。

possible_keys

显示了查询可以使用哪些索引,这是基于查询访问的列和使用的比较操作符来判断的

key

这一列显示了MySQL决定采用哪个索引来优化对该表的访问,如果索引没有出现在possible_keys列中,那么MySQL选用他是出于另外的原因。

key和possible_keys的区别

possible_keys揭示了哪一个索引能有助于高效进行查询,而key显示的是优化采用哪一个索引可以最小化查询成本。

key_len

key_len 字段表示 MySQL 在使用索引时,使用的索引长度(字节数),下面是详细解释:

  1. 如果索引是一个主键、唯一或普通索引,则 key_len 就是该索引的长度。
  2. 如果索引是一个联合索引(即包含多个字段的索引),则 key_len 表示索引中所有字段的长度之和。
  3. 如果索引只是一个前缀索引,则 key_len 表示前缀的长度,而不是整个字段的长度。
  4. 如果没有使用索引,则 key_len 为 NULL。

ref

用于表示当前查询所使用的索引列,以及使用了哪些表和哪些列进行了关联。
一般有以下两种情况:

  1. 如果是 a=1 这种情况,则为const
  2. 如果是表join的情况 a.t1=b.t1, 则列出具体的列。多个列以逗号隔开。

rows

这一列是MySQL估计为了找到所需要的行而要读取的行数。(不是实际读出来一定需要的行数,而是根据抽样法预估出来的行数)

filtered

Filter是查询的行数与总行数的比值。其实作用与rows差不多,都是数值越小,效率越高。

Extra

Using index

使用覆盖索引,防止回表

Using index condition

在MySQL 5.6版本后加入的新特性(Index Condition Pushdown);会先条件过滤索引,过滤完索引后找到所有符合索引条件的数据行,随后用 WHERE 子句中的其他条件去过滤这些数据行;

Using where

存储引擎检索后再进行过滤

Using temporary

结果排序时会使用一个临时表

参考

MySQL官方文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值