mysql-执行计划详解

Explain

Explain 有两个变种

  • explain extended

    会在explain的基础上额外提供一些查询优化的信息。紧随其后通过show warnings 命令可以得到优化后的查询语句,从而看出优化器优化了什么。额外还有一个filtered列

  • explain partitions

    相比 explain 多了一个partitions字段,如果查询是基于分区表的话,会显示查询将访问的分区

限制

  • EXPLAIN无法分析触发器、存储过程或UDF会如何影响查询
  • 不支持存储过程,尽管可以手动抽取SQL并单独对其进行explain分析
  • 不会分析MySQL在查询执行中所做的特定优化
  • 不会显示关于查询计划的所有信息
  • 不区分具有相同名称的事物。例如,它对内存排序和临时文件都使用“filesort”,并且对磁盘上和内存上的临时表都显示”Using Temporary“
  • 可能会误导

输出列说明

输出列说明
id编号是select的序列号,而且id的顺序是按照select出现的顺序增长的
select_type表示对应行的查询是简单还是复杂查询
table表示explain的这一行正在访问哪个表
partitions查询将从中匹配记录的分区
type表示关联类型或者访问类型,即MySQL决定如何查找表中的行,查找数据行记录的大概范围
possible_key显示查询可能使用哪些索引来查找
key显示MySQL实际使用那个索引来优化对该表的访问,如果没有索引,则该列是NULL
key_len显示了mysql在索引里的字节数,通过这个值可以计算出具体使用了索引中的那些列
ref显示了在key列记录中的索引中,表查找中的值所用到的列或常量
rowsMySQL估计要读取并检测的行数,并不是结果集里的行数
filtered指示按表条件过滤的表行的估计百分比。最大值为100,这表示未过滤行。值从100减小表示过滤量增加。 rows显示了检查的估计行数,rows× filtered显示了与下表连接的行数
Extra展示的是额外信息

select_type

输出项说明
SIMPLE简单查询。查询不包含子查询和union
PRIMARY复杂查询中最外层的select
UNION RESULT在union临时表检索结果的select
DEPENDENT UNIONUNION 取决于外部查询
SUBQUERY包含在select中的子查询(不在from子句中)
DEPENDENT SUBQUERY子查询取决于外部查询
DERIVED包含在from中的子查询。MySQL会将结果存放在一个临时表中,也称为派生表
DEPENDENT DERIVED派生表依赖于另一个表
MATERIALIZED物化子查询
UNION在union中的第二个和随后的select
UNCACHEABLE SUBQUERY子查询,其结果无法缓存,必须针对外部查询的每一行重新进行评估
UNCACHEABLE UNION属于不可缓存子查询的中的第二个或更高版本的选择

table列

  • <union*M*,*N*>:该行是指具有和id值的行 的 *M*并集 N
  • <derived*N*>:该行是指用于与该行的派生表结果id的值 N,派生表可能来自(例如)FROM子句中的子查询
  • <subquery*N*>:该行是指该行的物化子查询的结果,其id 值为*N*

type

依次从最优到最差为:system > const > eq_ref > ref > range > index > ALL
一般来说得保证查询达到 range 级别,最好达到 ref

输出项说明
NULL意味着MySQL能够在优化阶段分解查询语句,在执行阶段甚至用不着再访问表或索引
system该表只有一行(=系统表)。这是const联接类型的特例
const该表最多具有一个匹配行,该行在查询开始时读取。因为只有一行,所以优化器的其余部分可以将这一行中列的值视为常量。 const表非常快,因为它们只能读取一次
eq_ref可以用于使用=运算符进行比较的索引列 。比较值可以是常量,也可以是使用在此表之前读取的表中列的表达式
ref索引访问,它返回匹配某个单值的行,可能会找到多个符合条件的行
ref_or_nullref之上的一个变体,它意味着MySQL必须在初次查找的结果里进行第二次查找以找出NULL条目
index_merge此联接类型指示使用索引合并优化。在这种情况下,key输出行中的列包含使用的索引列表,并key_len包含使用的索引的最长键部分的列表
unique_subquery只是一个索引查找函数,它完全替代了子查询以提高效率
index_subquery此连接类型类似于 unique_subquery。它代替IN子查询,适用于子查询中的非唯一索引
range范围扫描,即有限制的索引扫描,它开始于索引的某一点,返回匹配这个值域的行
index扫描全表索引,这通常比ALL快一些(index是从索引中读取的,而all是从硬盘中读取的)
ALL全表扫描

index

扫描表时按照索引次序进行而不是行。它的主要优点是避免了排序;最大的缺点是要承担按索引次序读取整个表的开销

key_len

key_len 计算规则如下:

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

Extra列

输出项说明
Using index表示MySQL将使用覆盖索引,以避免访问表
Using whereMySQL将在存储引擎检索后再进行过滤
Using temporaryMySQL在对查询结果排序时会使用临时表
Using filesortMySQL会对结果使用一个外部索引排序,而不是按照索引次序从表里读取行
Range checked for each record(index map:N)没有好用的索引,新的索引将在连接的每一行上重新估算。N是显示在prossible_keys列中索引的位图,并且是冗余的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值