MySQL_Explain

Explain

查看执行计划,从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。

官方文档

适用范围:SELECTDELETEINSERTREPLACE,和 UPDATE语句。

Explain相关列

一、id

Select 查询中的序列号,表示查询中执行Select 的顺序或者操作表的顺序

  1. id相同从上至下顺序执行。

    执行顺序:T1,T2

    image.png
  2. id不同,id的序号会递增,id值大的先执行。

    执行顺序:T2,T1

    image.png
  3. id有相同有不同的情况下,id 大的先执行,id相同的从上到下执行

    执行顺序:T3,T1,T2

    image.png

二、select_type

查询类型,主要用于区分普通查询、联合查询、子查询等

select_type类型

select_typeValue JSON Name Meaning
SIMPLE None 简单的查询(不使用UNION或者子查询)
PRIMARY None 最外层的Select
UNION None 若第二个Select出现在UNION之后,则被标记为UNION;若UNION包含在FROM子句中,外层Select将被标记为:DERIVED
DEPENDENT UNION dependent (true) 在UNION中第二个或以后的Select语句,依赖于外部查询
UNION RESULT union_result 从UNION中获取表的结果的Select
SUBQUERY None 子查询
DEPENDENT SUBQUERY dependent (true) 依赖于外部查询的子查询
DERIVED None 派生表(临时表)
DEPENDENT DERIVED dependent (true) 派生表依赖于另一个表
MATERIALIZED materialized_from_subquery 物化子查询
UNCACHEABLE SUBQUERY cacheable (false) 无法缓存结果并且必须为外部查询的每一行重新评估的子查询
UNCACHEABLE UNION cacheable (false) UNION 属于不可缓存子查询的第二个或以后的选择
  1. SIMPLE

    image.png
  2. PRIMARY

    image.png
  3. UNION

    image.png
  4. UNION RESULT

    image.png
  5. SUBQUERY

    image.png

三、table

输出行所引用的表的名称,表名

四、type

访问类型,

从最好类型到最差类型:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > all

常用的从最好类型到最差类型:

system > const > eq_ref > ref > range > index > all

  1. system

    该表只有一行(= 系统表)。这是const连接类型的一个特例 。

  2. const

    该表最多有一个匹配行,在查询开始时读取。因为只有一行,该行中该列的值可以被优化器的其余部分视为常量。 const表非常快,因为它们只被读取一次。MySQL就能将查询转换为一个常量。

    SELECT * FROM tbl_name WHERE primary_key=1;
    
    SELECT * FROM tbl_name
      WHERE primary_key_part1=1 AND primary_key_part2=2;
    
    image.png
  3. eq_ref

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

    当连接使用索引的所有部分并且索引是一个 PRIMARY KEYUNIQUE NOT NULL索引时使用它。

    eq_ref可用于使用=运算符进行比较的索引列 。比较值可以是常量或表达式,该表达式使用在此表之前读取的表中的列。在以下示例中,MySQL 可以使用 eq_ref连接来处理 ref_table

    SELECT * FROM ref_table,other_table
      WHERE ref_table.key_column=other_table.column;
    
    SELECT * FROM ref_table,other_table
      WHERE ref_table.key_column_part1=other_table.column
      AND ref_table.key_column_part2=1;
    
    image.png
  4. ref

    如果联接仅使用键的最左边前缀,或者该键不是PRIMARY key或UNIQUE索引(换句话说,如果连接不能根据键值选择单行),则使用ref。如果所使用的键只匹配少数行,那么这是一种很好的连接类型。

    ref可用于使用=or<=> 运算符进行比较的索引列 。在以下示例中,MySQL 可以使用 ref连接来处理 ref_table

    SELECT * FROM ref_table WHERE key_column=expr;
    
    SELECT * FROM ref_table,other_table
      WHERE ref_table.key_column=other_table.column;
    
    SELECT * FROM ref_table,other_table
      WHERE ref_table.key_column_part1=other_table.column
      AND ref_table.key_column_part2=1;
    
  1. fulltext

    连接是使用FULLTEXT 索引执行的。

  2. ref_or_null

    这种连接类型类似于 ref,但另外,MySQL 会额外搜索包含NULL值的行。这种连接类型优化最常用于解析子查询。在以下示例中,MySQL 可以使用 ref_or_null连接来处理ref_table

    SELECT * FROM ref_table
      WHERE key_column=expr OR key_column IS NULL;
    
  3. index_merge

    此连接类型表示使用了索引合并优化。在这种情况下,key输出行中的列包含所使用索引的列表,并key_len包含所使用索引 的最长关键部分的列表。

    where 条件后可能有多个条件(或者 join )涉及到多个字段,他们之间进行 AND 或 OR,那么此时就有可能会用到 index_merge 技术; index_merge 技术如果简单的说就是:对多个索引分别进行条件扫描,然后将各自的结果进行合并(intersect/union)

  4. unique_subquery

    这种类型替代 了以下形式的eq_ref一些 IN子查询:

    value IN (SELECT primary_key FROM single_table WHERE some_expr)
    

    unique_subquery 只是一个索引查找函数,完全替换子查询以提高效率。

  5. index_subquery

    这种联接类型类似于 unique_subquery. 它取代了IN子查询,但它适用于以下形式的子查询中的非唯一索引:

    value IN (SELECT key_column FROM single_table WHERE some_expr)
    
  6. range

    只检索给定范围内的行,使用索引选择行。输出行中的键列指示使用哪个索引。key_len包含所使用的最长的密钥部分。对于这种类型,ref列是NULL。

    range当使用=, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, LIKE, 或 IN()运算符中的任何一个将键列与常量进行比较时,可以使用 :

    SELECT * FROM tbl_name
      WHERE key_column = 10;
    
    SELECT * FROM tbl_name
      WHERE key_column BETWEEN 10 and 20;
    
    SELECT * FROM tbl_name
      WHERE key_column IN (10,20,30);
    
    SELECT * FROM tbl_name
      WHERE key_part1 = 10 AND key_part2 IN (10,20,30);
    
  7. index

    index联接类型是一样的 ALL,只是索引树被扫描。这有两种方式:

    • 如果索引是查询的覆盖索引,并且可以用来满足表中所需的所有数据,则只扫描索引树。在本例中,Extra列显示Using index。仅索引扫描通常比ALL扫描快,因为索引的大小通常小于表数据。
    • 全表扫描是通过从索引中读取数据以按照索引顺序查找数据行来执行的。 Uses index不会出现在 Extra列中。

    当查询仅使用属于单个索引的列时,MySQL 可以使用此连接类型。

  8. ALL

    对先前表中的每个行组合进行全表扫描。如果该表是第一个未标记的表 const,这通常不好,并且在所有其他情况下通常 非常糟糕。通常,您可以ALL通过添加索引来避免 基于常量值或早期表中的列值从表中检索行。

五、possible_keys

显示可能应用在这张表的索引,一个或多个。

查询涉及到的字段上若存在索引,则该索引被列出。但是不一定被查询实际使用。

如果此列是NULL(或在 JSON 格式的输出中未定义),则没有相关索引。在这种情况下,您可以通过检查WHERE 子句来检查它是否引用了适合编制索引的某些列或多列,从而提高查询的性能

image.png

六、key

key列表示 MySQL 实际决定使用的键(索引),如果为 null,则没有用到索引。

查询中如果使用到了覆盖索引,则该索引仅出现在key列表中。

image.png

七、key_len

key_len表示使用的索引长度[字节数],key_len可以衡量索引的好坏,key_len越小 索引效果越好。

image.png

八、ref

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

九、rows

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

对于InnoDB表格,这个数字是一个估计值,可能并不总是准确的。

image.png

十、Extra

包含不适合在其他列中显示但十分重要的额外信息

  1. Using filesort (影响性能)

    MySQL 会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。

    MySQL中无法利用索引完成的排序操作称为 “文件排序”。

    1. 未使用文件排序情况

      image.png
    2. 使用文件排序情况

      image.png
  2. Using temporary (影响性能)

    使用了临时表保存中间结果,MySQL在对查询结果排序时使用临时表。常见于排序 order by 和分组查询 group by。

    该表存在的索引

    image-20210928151339321.png

    查看执行计划【用到了Using temporary】

    image.png

    查看执行计划【未用到Using temporary】,尽量按照索引顺序来,防止文件内排序。

    image.png
  3. Using index (表示使用到了索引覆盖)

    表示相应的Select 操作使用到了索引覆盖(Covering Index ),避免访问了表的数据行,效率不错!

    1. 如果同时出现 Using Where,表明索引被用来执行索引键值的查找。

      image.png
    2. 如果没有同时出现Using Where ,表明索引用来读取数据而非执行查找动作。

      image.png
  4. Using where

    表明使用了where过滤

    产生情况案例:

    image.png
  5. Using join buffer

    使用了连接缓存

    连接的表被读入连接缓冲区,然后它们的行从缓冲区中用于执行与当前表的连接。

  1. Impossible WHERE

    MySQL 已读取所有 const(和 system)表并注意到该WHERE子句始终为假。

    产生情况案例:

    image.png

你可能感兴趣的:(MySQL_Explain)