MySQL的explain

233 阅读8分钟

以下是使用 explain 查询语句执行计划的样例代码:

复制代码
explain select * from users where age > 18;

通过执行以上命令,可以看到查询语句的执行计划,包括以下信息:

explain展示的字段

  • id: 每个 SELECT 查询都会有一个唯一的编号,id 相同的行表示在同一个子查询中;
  • select_type: 查询的类型,可能是 SIMPLE、PRIMARY、SUBQUERY、DERIVED 等等,表示查询的复杂度和优化方式;
  • table: 表名;
  • partitions: 分区;
  • type: 访问表的方式,包括 system、const、eq_ref、ref、range、index、all 等等,从效率排列顺序依次递减;
  • possible_keys: 可能使用的索引;
  • key: 实际使用的索引;
  • key_len: 使用的索引的长度;
  • ref: 表示连接类型,如果是主键或唯一索引,则值为 const;否则为具体的列名;
  • rows: 表示扫描的行数,显示的行数越少,则查询速度越快;
  • filtered: 表示此表被查询的条件所过滤掉的记录比例;
  • Extra: 包含一些额外的执行信息和优化提示,如 Using index、Using where、Using temporary、Using filesort 等。

通过分析执行计划,可以找到查询语句存在哪些潜在问题,如可能出现的慢查询、死锁等,从而进行调整和优化。 MySQL 的 explain 命令返回的执行计划中,id 字段用于标识查询中每个 SELECT 语句的唯一编号。当一个查询中包含多个子查询时,每个子查询也会拥有自己的唯一编号。

id字段

在执行计划中,id 字段通常以数字形式出现,且表示的是查询执行顺序及之间的依赖关系。例如,若一个 SELECT 查询包含两个子查询,则 id 号越小的子查询先执行,且父查询 id 号比其子查询大。同样,若一个 SELECT 查询中包含多个 JOIN 操作,则 id 号较小的 JOIN 先执行。

在执行计划中,通过 id 字段可以查看出查询执行计划的逻辑顺序和执行顺序,辅助开发者进行 SQL 优化。

以下是一个例子,展示了 id 字段在 MySQL 中执行计划中的应用:

复制代码
id   select_type   table   partitions   type   possible_keys   key    key_len   ref     rows   filtered   Extra
1    PRIMARY       t1      <null>       ALL    <null>         <null> <null>    <null>  100    10.00      <null>
2    DERIVED       t2      <null>       ALL    <null>         <null> <null>    <null>  200    20.00      Using where

在执行计划中,可以看到该查询有两个子查询,其中 id=2 的子查询是由 id=1 的父查询生成的。 MySQL 的 explain 命令返回的执行计划中,type 字段用于指定访问表的方式。通过分析 type 字段可以了解查询过程的效率和性能瓶颈,从而进行 SQL 优化。

select_type展示的字段

MySQL 的 explain 命令返回的执行计划中,select_type 字段用于描述查询类型,例如简单查询、联合查询、子查询等。通过分析 select_type 字段可以了解查询过程的类型,从而进行 SQL 优化。

下面介绍 MySQL 中 select_type 字段的可能取值及其含义:

  • SIMPLE:表示简单 SELECT,不使用 UNION 或子查询;
  • PRIMARY:表示最外层的查询,即主查询;
  • DERIVED:表示从表中导出的临时表,常见于子查询或连接查询;
  • SUBQUERY:表示子查询中的第一个 SELECT;
  • UNION:表示 UNION 中的第二个或后面的 SELECT 语句;
  • UNION RESULT:表示 UNION 的结果集;
  • DEPENDENT UNION:表示 UNION 中的第二个或后面的 SELECT 依赖于外部查询(即前面的 SELECT);
  • DEPENDENT SUBQUERY:表示子查询中的第一个 SELECT 依赖于外部查询(即主查询);
  • UNCACHEABLE SUBQUERY:表示子查询不能被缓存,必须重新运行;
  • MATERIALIZED:表示使用了临时表存储子查询结果集。

例如,以下是 select_type 取值为 PRIMARY 的示例执行计划:

复制代码
id   select_type   table   partitions   type   possible_keys   key     key_len   ref    rows   filtered   Extra
1    PRIMARY       t1      <null>       ALL    <null>          <null>  <null>    <null> 100    100.00     <null>

在这个执行计划中,查询语句是主查询,对表 t1 进行了全表扫描。

以下是一个示例代码,展示如何使用 explain 命令获取执行计划:

复制代码
EXPLAIN SELECT * FROM table_name WHERE col1 = 'value' ORDER BY col2;

通过执行以上 SQL 语句并使用 explain 命令,可以得到查询的执行计划,包括 select_type 字段。

type字段

下面介绍 MySQL 中 type 字段的可能取值及其含义:

  • system:表示只有一行记录(系统表),这是 const 类型的特例;
  • const:表示查询的是主键或唯一索引,最多匹配一行记录;
  • eq_ref:表示使用了连接(JOIN)操作,关联的索引是主键或唯一索引,每个表最多匹配一行记录;
  • ref:表示使用了普通索引进行查询,返回匹配某个单独值的所有行;
  • range:表示通过索引范围查找记录,常见于使用了 <、>、<=、>= 等或 BETWEEN、IN 等查询;
  • index:表示扫描全表或索引,该类型查询效率较低,应尽量避免使用;
  • all:表示全表扫描,效率最低,应尽量避免使用。

例如,以下是 type 取值为 ref 的示例执行计划:

复制代码
id   select_type   table   partitions   type   possible_keys   key     key_len   ref           rows   filtered   Extra
1    SIMPLE        t1      <null>       ref    idx_col1       idx_col1 5         const,const  10     100.00     <null>

在这个执行计划中,查询语句在表 t1 上使用了索引 idx_col1,并且只返回匹配某个单独值的记录。

filtered字段

MySQL 的 explain 命令返回的执行计划中,filtered 字段用于描述查询结果集经过哪些条件过滤,即过滤后剩余的行数所占比例。 通过分析 filtered 字段可以了解查询结果集的过滤情况,从而进行 SQL 优化。

filtered 字段的取值范围在 0 到 100 之间,表示结果集中剩余的行数所占比例。例如,如果 filtered 取值为 90.00,则表示结果集中的行数经过过滤只剩下原来的 90%。

需要注意的是,这个过滤是基于所有表的大致估算值,因此只是一个近似的值,并不是精确的值。

以下是一个示例代码,展示如何使用 explain 命令获取执行计划:

复制代码
EXPLAIN SELECT * FROM table_name WHERE col1 = 'value' ORDER BY col2;

通过执行以上 SQL 语句并使用 explain 命令,可以得到查询的执行计划,包括 filtered 字段。

ref字段

MySQL 的 explain 命令返回的执行计划中,ref 字段用于描述表之间的关联关系,即连接操作的对象。通过分析 ref 字段可以了解查询过程中的连接操作涉及到哪些表和字段,从而进行 SQL 优化。

ref 字段表示连接时使用哪个索引,并包含了连接类型和被连接表的列名。如果有多个表被连接,则 ref 字段会重复出现。

以下是 ref 字段的可能取值及其含义:

  • const:表示通过常数表达式匹配,通常出现在主键或唯一键的查询条件中;
  • eq_ref:表示被连接的表只有一行匹配(使用唯一索引),常常发生在主键或唯一键的连接操作中,例如 a JOIN b ON a.id = b.a_id
  • ref:表示使用普通的非唯一性索引进行连接;
  • fulltext:表示使用全文索引进行连接;
  • ref_or_null:表示使用普通的非唯一性索引和 NULL 值进行连接;
  • index_merge:表示使用索引合并进行连接,即使用多个索引中的若干个进行连接;
  • unique_subquery:表示子查询中使用唯一索引进行连接;
  • index_subquery:表示子查询中使用非唯一性索引进行连接;
  • range:表示使用索引范围查找进行连接;
  • index:表示进行全表扫描或使用索引搜索进行连接操作。

以下是一个示例代码,展示如何使用 explain 命令获取执行计划:

复制代码
EXPLAIN SELECT * FROM table1 JOIN table2 ON table1.id = table2.table1_id WHERE table1.col1 = 'value';

通过执行以上 SQL 语句并使用 explain 命令,可以得到查询的执行计划,包括 ref 字段。

Extra字段

MySQL 的 explain 命令返回的执行计划中,Extra 字段用于提供与查询有关的额外信息,例如使用了哪些索引、使用了哪些算法等。通过分析 Extra 字段可以了解查询过程的详细信息,从而进行 SQL 优化。

下面介绍 MySQL 中 Extra 字段的可能取值及其含义:

  • Using index:表示使用了覆盖索引,即查询所需的所有列都包含在索引中,避免了回表;
  • Using where:表示使用了 WHERE 子句进行条件过滤;
  • Using temporary:表示使用了临时表来存储结果集;
  • Using filesort:表示使用了文件排序算法(外部排序);
  • Using join buffer:表示使用了连接缓存;
  • Impossible where:表示条件不满足,查询将返回空结果集;
  • Select tables optimized away:表示某个查询被优化为常量表达式,例如 SELECT 1+2;。

例如,以下是 Extra 取值为 Using where; Using index 的示例执行计划:

复制代码
id   select_type   table   partitions   type   possible_keys   key     key_len   ref       rows   filtered   Extra
1    SIMPLE        t1      <null>       ref    idx_col1       idx_col1 5         const     10     100.00     Using where; Using index

在这个执行计划中,查询语句在表 t1 上使用了索引 idx_col1 进行条件过滤,并且使用了覆盖索引。

以下是一个示例代码,展示如何使用 explain 命令获取执行计划:

复制代码
EXPLAIN SELECT * FROM table_name WHERE col1 = 'value' ORDER BY col2;

通过执行以上 SQL 语句并使用 explain 命令,可以得到查询的执行计划,包括 Extra 字段。