mysql通过explain获取查询执行计划的信息

60次阅读
没有评论

共计 3620 个字符,预计需要花费 10 分钟才能阅读完成。

这篇文章主要介绍“mysql 通过 explain 获取查询执行计划的信息”,在日常操作中,相信很多人在 mysql 通过 explain 获取查询执行计划的信息问题上存在疑惑,丸趣 TV 小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”mysql 通过 explain 获取查询执行计划的信息”的疑惑有所帮助!接下来,请跟着丸趣 TV 小编一起来学习吧!

explain 获取查询执行计划的信息
查询中的 select 关键字之前增加 explain,执行查询时返回有关于执行计划中的每一步信息。
mysql select 1\G;
*
1. row
*
1: 1
1 row in set (0.00 sec)

ERROR:
No query specified

mysql explain select 1\G;
*
1. row
*
  id: 1
 select_type: SIMPLE
table: NULL
  partitions: NULL
type: NULL
possible_keys: NULL
 key: NULL
 key_len: NULL
 ref: NULL
rows: NULL
filtered: NULL
Extra: No tables used
1 row in set, 1 warning (0.00 sec)

ERROR:
No query specified

explain 两个变种
explain extended:告诉服务器“逆向编译”执行计划为一个 select 语音,可以通过紧接其后运行 show warnings 看到这个生成的语句。这个语句直接来自执行计

划,而不是原 sql 语句,到这个点上已经变成一个数据结构。可以检测查询优化器到底是如何转化语句的。explain extended 在 Mysql 和更新后版本中可用
explain partitions 会显示查询将访问的分区,如果查询是基于分区表。在 Mysql5.1 和更新版本中存在。

explain 中的列
id 列
编号,标识 select 所属行,如果在语句当中没有子查询或联合,那么只有唯一的 select,于是每一行在这个列中都将显示 1. 否则内层的 select 语句一般会顺序编

,对应其在原始语句中的位置
mysql 将 select 查询分为简单和复杂类型,复杂类型可分为三大类: 简单子查询、所谓的派生表(from 子句中的子查询)、UNION 查询。

例:
简单查询:select 1;
复杂 - 简单子查询:select(select 1 from us_user limit 1) from us_user_role;
复杂 - 派生表:select * from us_user where id in (select user_id from us_user_role);
复杂 union 查询:select 1 union select 2;

select_type 列
显示对应行是简单还是复杂的 select,如果是复杂 select,显示是三种复杂类型中的哪一种。SIMPLE 值意味着查询不包括子查询和 union。如果查询有任何复杂的

子部分,则最外层部分标记为 PRIMARY,其他部分标记如下。

SUBQUERY:包含在 select 列表中的子查询中的 select(不在 from 子句中)标记为 subquery。
DERIVED:包含在 FROM 子句的子查询中的 select,MYSQL 会递归执行并将结果放到一个临时表中,服务器内部称其“派生表”,因为该临时表从子查询中派生来的
UNION:在 UNION 中第二个和随后的 select 被标记为 UNION
UNION RESULT:用来从 UNION 的匿名临时表检索的 SELECT 标记为 UNION RESULT.

table 列
显示对应正在访问那个表。或者该表的别名(如果 sql 中定义了别名)
当 from 子句中有子查询时,table 列是格式,表示当前查询依赖 id=N 的查询,于是先执行 id=N 的查询。当有 union 时,UNION RESULT 的

table 列的值为,1 和 2 表示参与 union 的 select 行 id。

partitions
访问的分区

type
表示管理类型或访问类型,即 mysql 决定如何查找表中的行。
依次从最优到最差分别为:system const eq_ref ref fulltext ref_or_null index_merge unique_subquery index_subquery range

index ALL

const, system:mysql 能对查询的某部分进行优化并将其转化成一个常量(可以看 show warnings 的结果)。用于 primary key 或 unique key 的所有列与常数

比较时,所以表最多有一个匹配行,读取 1 次,速度比较快。

eq_ref:primary key 或 unique key 索引的所有部分被连接使用,最多只会返回一条符合条件的记录。这可能是在 const 之外最好的联接类型了,简单的

select 查询不会出现这种 type。

ref:相比 eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前缀,索引要和某个值相比较,可能会找到多个符合条件的行。

ref_or_null:类似 ref,但是可以搜索值为 NULL 的行。

index_merge:表示使用了索引合并的优化方法。

range:范围扫描通常出现在 in(), between , , , = 等操作中。使用一个索引来检索给定范围的行。

index:和 ALL 一样,不同就是 mysql 只需扫描索引树,这通常比 ALL 快一些。

ALL:即全表扫描,意味着 mysql 需要从头到尾去查找所需要的行。通常情况下这需要增加索引来进行优化了

NULL:mysql 能够在优化阶段分解查询语句,在执行阶段用不着再访问表或索引。例如:在索引列中选取最小值,可以单独查找索引来完成,不需要在执行时访问

possible_keys 列
显示查询可以使用那些索引。
explain 时可能出现 possible_keys 有值,而 key 显示 NULL 的情况,这种情况是因为表中数据不多,mysql 认为索引对此查询帮助不大,选择了全表查询。
如果该列是 NULL,则没有相关的索引。在这种情况下,可以通过检查 where 子句看是否可以创造一个适当的索引来提高查询性能,然后用 explain 查看效果。

key 列
这一列显示 mysql 实际采用哪个索引来优化对该表的访问。
如果没有使用索引,则该列是 NULL。如果想强制 mysql 使用或忽视 possible_keys 列中的索引,在查询中使用 force index、ignore index。

key_len 列
这一列显示了 mysql 在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列。

key_len 计算规则如下:

字符串
char(n):n 字节长度
varchar(n):2 字节存储字符串长度,如果是 utf-8,则长度 3n + 2
数值类型
tinyint:1 字节
smallint:2 字节
int:4 字节
bigint:8 字节
时间类型
date:3 字节
timestamp:4 字节
datetime:8 字节
如果字段允许为 NULL,需要 1 字节记录是否为 NULL
索引最大长度是 768 字节,当字符串过长时,mysql 会做一个类似左前缀索引的处理,将前半部分的字符提取出来做索引。

ref 列
这一列显示了在 key 列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量),func,NULL

rows 列
这一列是 mysql 估计要读取并检测的行数,注意这个不是结果集里的行数。

filtered 列
显示针对表里面符合某个条件(Where 子句或联接条件)的记录数的百分比做一个悲观估算,如果把 rows 列和这个百分比相乘,就能看到 mysql 估算他将和查询记

录里面前一个表关联的行数。

Extra 列
包含的是不适合其他列显示的额外信息。
常见的最重要的值如下:

Using index:这发生在对表的请求列都是同一索引的部分的时候,返回的列数据只使用了索引中的信息,而没有再去访问表中的行记录。是性能高的表现。
distinct: 一旦 mysql 找到了与行相联合匹配的行,就不再搜索了
Using where:mysql 服务器将在存储引擎检索行后再进行过滤。就是先读取整行数据,再按 where 条件进行检查,符合就留下,不符合就丢弃。
Using temporary:mysql 需要创建一张临时表来处理查询。出现这种情况一般是要进行优化的,首先是想到用索引来优化。
Using filesort:mysql 会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。此时 mysql 会根据联接类型浏览所有符合条件的记录,并保存排序关键字和行指针,然后排序关键字并按顺序检索行信息。这种情况下一般也是要考虑使用索引来优化的。

到此,关于“mysql 通过 explain 获取查询执行计划的信息”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注丸趣 TV 网站,丸趣 TV 小编会继续努力为大家带来更多实用的文章!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-28发表,共计3620字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)