执行计划

  • 使用explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是怎么处理你的语句的。分析你的语句或者是表结构的性能瓶颈

语法

  • explain + sql语句

执行计划的作用

  • 表的读取顺序
  • 数据读取操作的操作类型
  • 哪些索引可以使用
  • 哪些索引被实际使用
  • 表之间的引用
  • 每张表有多少行被优化器查询

执行计划包含的信息

id

  • select查询的序列号,包含一组数字。表示查询中执行select子句或操作表的顺序
  • 存在以下三种情况
    • id相同,执行顺序由上至下
    • id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行
    • id相同不同,同时存在

select_type

  • 查询的类型,主要是用于区别普通查询、联合查询、子查询等的复杂查询
  • 存在以下几种值
    • SIMPLE: 简单的select查询,查询中不包含子查询或者union
    • PRIMARY: 查询中若包含任何复杂的子部分,最外层查询则被标记为primary
    • SUBQUERY: 在select或where列表中包含子查询
    • DERIVED: 在from列表中包含的子查询被标记为derived。mysql会递归执行这些子查询,把结果放在临时表里。
    • UNION: 若第二个select出现在union之后,则被标记为union;若union包含在from子句的子查询中,外层select将被标记为derived
    • UNION RESULT: 从union表获取结构的select

table

  • 显示这一行的数据是出自哪张表


    执行计划_第1张图片

type

  • 访问类型

  • 结果值从最好到最坏依次为: system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range> index > ALL

  • system:表只有一行记录,这是const类型特例,平时不会出现

  • const:表示通过索引一次就找到了。const用于比较primary key或者unique索引。因为只匹配一行数据,所以很快。

  • eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描

  • ref:非唯一性索引扫描,返回匹配某个单独值的所有行。本质上也是一种索引访问。它返回所有匹配某个单独值的行。然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体

  • index:当查询的结果全为索引列的时候,会扫描整个索引文件,不去扫描正式的数据文件

  • range:只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引。一般就是在where语句中出现了between、<、>、in等的查询。这种范围扫描索引扫描比全表扫描好,因为它只需要开始于索引的某一点,结束于另一点,不用扫描全部索引

  • ALL:全表扫描,将遍历全表找到匹配的行

possiblle_keys

  • possiblle_keys: 可能会使用到的索引

key

  • key:实际使用到的索引,如果为NULL,则没有使用到索引
  • 查询中若使用了覆盖索引,则该索引和查询的select字段重叠

key_len

  • 索引的长度

  • key_len表示索引使用的字节数,可以通过该列计算查询中使用的索引的长度。在不损失精度的情况下,长度越短越好

  • key_len显示的值为索引字段的最大可能长度,并非实际使用长度。即key_len是根据表定义计算而得,不是通过表内检索出的

  • 根据底层使用的不同存储引擎,受影响的行数这个指标可能是一个估计值,也可能是一个精确值。即使受影响的函数是一个估计值(例如当使用InnoDB存储引擎管理表存储时),通常情况下这个估计值也足以使优化器做出一个有充分依据的决定。

  • 根据这个值,就可以判断索引使用情况,特别是在组合索引的时候,判断所有的索引字段是否都被查询到

  • char和varcahr跟字符编码也有密切的联系

  • latin1占用1个字节,gbk占用2个字节,utf8占用3个字节。(不同字符编码占用的存储空间不同)

执行计划_第2张图片
  • key_len的计算
    • 字符类型

      • 字符类型 - 索引字段为char类型 + 不可为Null时

        • char字段的长度 * (utf8=3,gbk=2,latin1=1)
      • 字符类型 - 索引字段为char类型 + 允许为Null时

        • char字段的长度 * (utf8=3,gbk=2,latin1=1) + 1(null)
      • 索引字段为varchar类型 + 不可为Null时:

        • varchar(n)变长字段 + 不允许Null = n*(utf8=3,gbk=2,latin1=1) + 2
      • 索引字段为varchar类型 + 允许为Null时:

        • varchar(n)变长字段 + 不允许Null = n*(utf8=3,gbk=2,latin1=1) + 1(Null) + 2
      • 变长字段需要额外的2个字节(varchar值保存时只保存需要的字符树,另加一个字节来记录长度,如果列声明的长度超过255,则使用两个字节,所以varchar索引长度计算的时候要加2),固定长度字段不需要额外的字节

      • 而NULL都需要1个字节的额外空间,所以索引字段最好不要为NULL。因为NULL让统计更加复杂并且需要额外的存储空间。

      • 复合索引有最左前缀的特性,如果复合索引能全部用上,则是符合索引字段的索引长度之和。这也可以用来判定复合索引是否部分能用还是全部能用

    • 数值类型


      执行计划_第3张图片
    • 整数/浮点数 类型的索引长度

      • not null = 字段本身的字段长度
      • null = 字段本身的字段长度 + 1(因为需要有是否为空的标记,这个标记需要占用1个字节)
    • datetime类型在5.6中字段长度是5个字节,datetime类型在5.5中字段长度是8个字节

ref

  • 显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或常量被用于查找索引列上的值

rows

  • rows: 根据表统计信息及索引使用情况,大致估算出找到所需的记录需要读取的行数

Extra

  • 包含不适合在其他列中显示但是十分重要的额外信息
描述
Using filesort 说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。
MySQL中无法利用索引完成的排序操作称为“文件排序”
Using temporary 使了用临时表保存中间结果,MySQL在对查询结果排序时使用临时表。
常见于排序order by 和分组查询 group by。
Using index 是否用了覆盖索引
Using where 表明使用了where过滤
Using join buffer 使用了连接缓存
Impossible where where子句的值总是false,不能用来获取任何元组

你可能感兴趣的:(执行计划)