mysql 执行计划 explain命令 详解

发布于:2025-06-21 ⋅ 阅读:(13) ⋅ 点赞:(0)

explain

在这里插入图片描述

  • id :select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序
  • select_type:查询类型 或者是 其他操作类型
  • table :正在访问哪个表
  • partitions :匹配的分区
  • type :访问的类型,评价sql性能的一个指标
  • possible_keys :显示可能应用在这张表中的索引,一个或多个,但不一定实际使用到
  • key :实际使用到的索引,如果为NULL,则没有使用索引
  • key_len :表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度
  • ref :显示索引的哪一列被使用了,如果可能的话,是一个常数,哪些列或常量被用于查找索引列上的值
  • rows :根据表统计信息及索引选用情况,大致估算出找到所需的记录所需读取的行数
  • filtered :表示符合查询条件的数据占全部数据的百分比
  • Extra :包含不适合在其它列中显示但十分重要的额外信息

select_type

  • SIMPLE: 简单查询,不包含子查询或UNION。
  • PRIMARY: 主查询,包含子查询时最外层的查询。
  • SUBQUERY: 子查询,出现在SELECT或WHERE中的独立子查询。
  • DEPENDENT SUBQUERY: 相关子查询,结果依赖于外部查询的列。
  • UNCACHEABLE SUBQUERY: 无法缓存的子查询(如含随机函数或变量)。
  • UNION: UNION操作中第二个或后续的SELECT语句。
  • UNION RESULT: UNION操作的结果集。
  • DERIVED: 派生表(子查询在FROM子句中)。
  • MATERIALIZED: 物化子查询,结果被存储为临时表供后续使用。

type单表访问方法

连接类型,有如下几种取值,性能从好到坏排序 如下:

  • null:MySQL能够在优化阶段分解查询语句,在执行阶段用不着再访问表或索引,如select 1;

  • system:该表只有一行(相当于系统表),system是const类型的特例

  • const:“常数”,针对主键或唯一索引的等值查询扫描, 最多只返回一行数据。 const 查询速度非常快, 因为它仅仅读取一次即可

  • eq_ref:当使用了索引的全部组成部分,并且索引是PRIMARY KEY或UNIQUE NOT NULL 才会使用该类型,性能仅次于system及const。

  • ref:搜索条件为二 级索引列与常数进行得值比较,形成的扫描区为单点扫描区间 采用二级索引来执行查询"的访问方法称为 ref。

  • fulltext:全文索引

  • ref_or_null:该类型类似于ref,但是MySQL会额外搜索哪些行包含了NULL。这种类型常见于解析子查询

  • index_merge:此类型表示使用了索引合并优化,表示一个查询里面用到了多个索引

  • unique_subquery:该类型和eq_ref类似,但是使用了IN查询,且子查询是主键或者唯一索引。

  • range

    SELECT * FROM single_table WHERE key2 IN (1438, 6328) OR (key2 >= 38 AND key2 <= 79);

    ​ 如果使用 idx_key2 执行该查询,那么对应的扫描区间就是 [1438, 1438]、[6328, 6328] 以及 [38, 79]。设计 MySQL 的大叔把“使用索引执行查询时,对应的扫描区间为若干个单点扫描区间或者范围扫描区间”的访问方法称为 range(仅包含一个单点扫描区间的访问方法不能称为 range 访问方法,扫描区间为 (−∞,+∞) 的访问方法也不能称为 range 访问方法)。

    ​ 范围扫描,表示检索了指定范围的行,主要用于有限制的索引扫描。比较常见的范围扫描是带有BETWEEN子句或WHERE子句里有>、>=、<、<=、IS NULL、<=>、BETWEEN、LIKE、IN()等操作符。

  • index:全索引扫描,和ALL类似,只不过index是全盘扫描了索引的数据。当查询仅使用索引中的一部分列时,可使用此类型。有两种场景会触发:

    • 如果索引是查询的覆盖索引,并且索引查询的数据就可以满足查询中所需的所有数据,则只扫描索引树。此时,explain的Extra 列的结果是Using index。index通常比ALL快,因为索引的大小通常小于表数据。
    • 按索引的顺序来查找数据行,执行了全表扫描。此时,explain的Extra列的结果不会出现Uses index。
  • ALL:全表扫描,性能最差。直接扫描主键索引叶子节点文件

extra

展示有关本次查询的附加信息,取值如下:

  • Using filesort:当Query 中包含 ORDER BY 操作,而且无法利用索引完成排序操作的时候,MySQL Query Optimizer 不得不选择相应的排序算法来实现。数据较少时从内存排序,否则从磁盘排序。Using tempporary:在对MySQL查询结果进行排序时,使用了临时表,这样的查询效率是比外部排序更低的,常见于order by和group by。

  • Using index:使用了索引覆盖

  • Using where:使用了where进行过滤,即使用到了索引,如果没有索引,说明是去聚集索引全盘扫描,说明没用到where进行过滤,只用where进行判断

  • Using index condition:使用了索引下推

  • Using MRR:使用了Multi-Range Read优化

  • Using join buffer:使用了连接缓存,比如说在查询的时候,多表join的次数非常多,那么将配置文件中的缓冲区的join buffer调大一些

  • Distinct:查找distinct值,当找到第一个匹配的行后,就不再搜索了

  • id :select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序

  • select_type:查询类型 或者是 其他操作类型

  • table :正在访问哪个表

  • partitions :匹配的分区

  • type :访问的类型,评价sql性能的一个指标

  • possible_keys :显示可能应用在这张表中的索引,一个或多个,但不一定实际使用到

  • key :实际使用到的索引,如果为NULL,则没有使用索引

  • key_len :表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度

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

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

  • filtered :表示符合查询条件的数据占全部数据的百分比

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

select_type

  • SIMPLE: 简单查询,不包含子查询或UNION。
  • PRIMARY: 主查询,包含子查询时最外层的查询。
  • SUBQUERY: 子查询,出现在SELECT或WHERE中的独立子查询。
  • DEPENDENT SUBQUERY: 相关子查询,结果依赖于外部查询的列。
  • UNCACHEABLE SUBQUERY: 无法缓存的子查询(如含随机函数或变量)。
  • UNION: UNION操作中第二个或后续的SELECT语句。
  • UNION RESULT: UNION操作的结果集。
  • DERIVED: 派生表(子查询在FROM子句中)。
  • MATERIALIZED: 物化子查询,结果被存储为临时表供后续使用。

type单表访问方法

连接类型,有如下几种取值,性能从好到坏排序 如下:

  • null:MySQL能够在优化阶段分解查询语句,在执行阶段用不着再访问表或索引,如select 1;

  • system:该表只有一行(相当于系统表),system是const类型的特例

  • const:“常数”,针对主键或唯一索引的等值查询扫描, 最多只返回一行数据。 const 查询速度非常快, 因为它仅仅读取一次即可

  • eq_ref:当使用了索引的全部组成部分,并且索引是PRIMARY KEY或UNIQUE NOT NULL 才会使用该类型,性能仅次于system及const。

  • ref:搜索条件为二 级索引列与常数进行得值比较,形成的扫描区为单点扫描区间 采用二级索引来执行查询"的访问方法称为 ref。

  • fulltext:全文索引

  • ref_or_null:该类型类似于ref,但是MySQL会额外搜索哪些行包含了NULL。这种类型常见于解析子查询

  • index_merge:此类型表示使用了索引合并优化,表示一个查询里面用到了多个索引

  • unique_subquery:该类型和eq_ref类似,但是使用了IN查询,且子查询是主键或者唯一索引。

  • range

    SELECT * FROM single_table WHERE key2 IN (1438, 6328) OR (key2 >= 38 AND key2 <= 79);

    ​ 如果使用 idx_key2 执行该查询,那么对应的扫描区间就是 [1438, 1438]、[6328, 6328] 以及 [38, 79]。设计 MySQL 的大叔把“使用索引执行查询时,对应的扫描区间为若干个单点扫描区间或者范围扫描区间”的访问方法称为 range(仅包含一个单点扫描区间的访问方法不能称为 range 访问方法,扫描区间为 (−∞,+∞) 的访问方法也不能称为 range 访问方法)。

    ​ 范围扫描,表示检索了指定范围的行,主要用于有限制的索引扫描。比较常见的范围扫描是带有BETWEEN子句或WHERE子句里有>、>=、<、<=、IS NULL、<=>、BETWEEN、LIKE、IN()等操作符。

  • index:全索引扫描,和ALL类似,只不过index是全盘扫描了索引的数据。当查询仅使用索引中的一部分列时,可使用此类型。有两种场景会触发:

    • 如果索引是查询的覆盖索引,并且索引查询的数据就可以满足查询中所需的所有数据,则只扫描索引树。此时,explain的Extra 列的结果是Using index。index通常比ALL快,因为索引的大小通常小于表数据。
    • 按索引的顺序来查找数据行,执行了全表扫描。此时,explain的Extra列的结果不会出现Uses index。
  • ALL:全表扫描,性能最差。直接扫描主键索引叶子节点文件

extra

展示有关本次查询的附加信息,取值如下:

  • Using filesort:当Query 中包含 ORDER BY 操作,而且无法利用索引完成排序操作的时候,MySQL Query Optimizer 不得不选择相应的排序算法来实现。数据较少时从内存排序,否则从磁盘排序。Using tempporary:在对MySQL查询结果进行排序时,使用了临时表,这样的查询效率是比外部排序更低的,常见于order by和group by。

  • Using index:使用了索引覆盖

  • Using where:使用了where进行过滤,即使用到了索引,如果没有索引,说明是去聚集索引全盘扫描,说明没用到where进行过滤,只用where进行判断

  • Using index condition:使用了索引下推

  • Using MRR:使用了Multi-Range Read优化

  • Using join buffer:使用了连接缓存,比如说在查询的时候,多表join的次数非常多,那么将配置文件中的缓冲区的join buffer调大一些

  • Distinct:查找distinct值,当找到第一个匹配的行后,就不再搜索了

  • id :select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序

  • select_type:查询类型 或者是 其他操作类型

  • table :正在访问哪个表

  • partitions :匹配的分区

  • type :访问的类型,评价sql性能的一个指标

  • possible_keys :显示可能应用在这张表中的索引,一个或多个,但不一定实际使用到

  • key :实际使用到的索引,如果为NULL,则没有使用索引

  • key_len :表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度

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

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

  • filtered :表示符合查询条件的数据占全部数据的百分比

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

select_type

  • SIMPLE: 简单查询,不包含子查询或UNION。
  • PRIMARY: 主查询,包含子查询时最外层的查询。
  • SUBQUERY: 子查询,出现在SELECT或WHERE中的独立子查询。
  • DEPENDENT SUBQUERY: 相关子查询,结果依赖于外部查询的列。
  • UNCACHEABLE SUBQUERY: 无法缓存的子查询(如含随机函数或变量)。
  • UNION: UNION操作中第二个或后续的SELECT语句。
  • UNION RESULT: UNION操作的结果集。
  • DERIVED: 派生表(子查询在FROM子句中)。
  • MATERIALIZED: 物化子查询,结果被存储为临时表供后续使用。

type单表访问方法

连接类型,有如下几种取值,性能从好到坏排序 如下:

  • null:MySQL能够在优化阶段分解查询语句,在执行阶段用不着再访问表或索引,如select 1;

  • system:该表只有一行(相当于系统表),system是const类型的特例

  • const:“常数”,针对主键或唯一索引的等值查询扫描, 最多只返回一行数据。 const 查询速度非常快, 因为它仅仅读取一次即可

  • eq_ref:当使用了索引的全部组成部分,并且索引是PRIMARY KEY或UNIQUE NOT NULL 才会使用该类型,性能仅次于system及const。

  • ref:搜索条件为二 级索引列与常数进行得值比较,形成的扫描区为单点扫描区间 采用二级索引来执行查询"的访问方法称为 ref。

  • fulltext:全文索引

  • ref_or_null:该类型类似于ref,但是MySQL会额外搜索哪些行包含了NULL。这种类型常见于解析子查询

  • index_merge:此类型表示使用了索引合并优化,表示一个查询里面用到了多个索引

  • unique_subquery:该类型和eq_ref类似,但是使用了IN查询,且子查询是主键或者唯一索引。

  • range

    SELECT * FROM single_table WHERE key2 IN (1438, 6328) OR (key2 >= 38 AND key2 <= 79);

    ​ 如果使用 idx_key2 执行该查询,那么对应的扫描区间就是 [1438, 1438]、[6328, 6328] 以及 [38, 79]。设计 MySQL 的大叔把“使用索引执行查询时,对应的扫描区间为若干个单点扫描区间或者范围扫描区间”的访问方法称为 range(仅包含一个单点扫描区间的访问方法不能称为 range 访问方法,扫描区间为 (−∞,+∞) 的访问方法也不能称为 range 访问方法)。

    ​ 范围扫描,表示检索了指定范围的行,主要用于有限制的索引扫描。比较常见的范围扫描是带有BETWEEN子句或WHERE子句里有>、>=、<、<=、IS NULL、<=>、BETWEEN、LIKE、IN()等操作符。

  • index:全索引扫描,和ALL类似,只不过index是全盘扫描了索引的数据。当查询仅使用索引中的一部分列时,可使用此类型。有两种场景会触发:

    • 如果索引是查询的覆盖索引,并且索引查询的数据就可以满足查询中所需的所有数据,则只扫描索引树。此时,explain的Extra 列的结果是Using index。index通常比ALL快,因为索引的大小通常小于表数据。
    • 按索引的顺序来查找数据行,执行了全表扫描。此时,explain的Extra列的结果不会出现Uses index。
  • ALL:全表扫描,性能最差。直接扫描主键索引叶子节点文件

extra

展示有关本次查询的附加信息,取值如下:

  • Using filesort:当Query 中包含 ORDER BY 操作,而且无法利用索引完成排序操作的时候,MySQL Query Optimizer 不得不选择相应的排序算法来实现。数据较少时从内存排序,否则从磁盘排序。Using tempporary:在对MySQL查询结果进行排序时,使用了临时表,这样的查询效率是比外部排序更低的,常见于order by和group by。
  • Using index:使用了索引覆盖
  • Using where:使用了where进行过滤,即使用到了索引,如果没有索引,说明是去聚集索引全盘扫描,说明没用到where进行过滤,只用where进行判断
  • Using index condition:使用了索引下推
  • Using MRR:使用了Multi-Range Read优化
  • Using join buffer:使用了连接缓存,比如说在查询的时候,多表join的次数非常多,那么将配置文件中的缓冲区的join buffer调大一些
  • Distinct:查找distinct值,当找到第一个匹配的行后,就不再搜索了

网站公告

今日签到

点亮在社区的每一天
去签到