EXPLAIN 语句提供有关 MySQL 如何执行语句的信息。 EXPLAIN 适用于 SELECT、DELETE、INSERT、REPLACE 和 UPDATE 语句。
EXPLAIN 为 SELECT 语句中使用的每个表返回一行信息。它按照MySQL在处理语句时读取表的顺序列出。这意味着MySQL从第一个表中读取一行,然后在第二个表中查找匹配的行,然后在第三个表中查找匹配的行,依此类推。处理完所有表后,MySQL会输出所选列,并通过列表回溯,找到所有数据。从此表中读取下一行,并继续下一个查询。
Column JSON Name Meaning
id select_id SELECT 标识符
select_type None SELECT 类型
table table_name 输出行的表
partitions partitions 匹配的分区
type access_type 联接类型
possible_keys possible_keys 可供选择的可能索引
key key 实际选择的索引
key_len key_length 所选密钥的长度
ref ref 与索引比较的列
rows rows 要检查的行的估计值
filtered filtered 按表条件筛选的行的百分比
Extra None 其他信息
  • id列:select 对应的id号,从1开始自增,执行顺序如下

    1. id相同,自上而下
    2. id不同,从大到小执行
    3. 如果显示null,最后执行,表示引用其他行的并集结果

  • type列:表示如何查询表

    • system

      该表只有一行数据

    • const

      该表最多有一个匹配的行,该行在查询开始时读取。由于只有一行,因此此行中列的值可以被优化器视为常量,意味着优化器在后续的处理中可以把从这唯一一行中得到的值当作常数来对待。 常量表非常快,因为它们只读取一次。

      SELECT * FROM tbl_name WHERE primary_key=1;

      SELECT * FROM tbl_name
      WHERE primary_key_part1=1 AND primary_key_part2=2;
    • eq_ref

      对于前一个表中的每个行数据,只对应此表的一行数据(前表与当前表是 多或一对一)。除了 system 和 const 类型之外,这是最好的连接类型。当联接使用索引并且索引是 PRIMARY KEY 或 UNIQUE 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;
    • ref

      对于上一个表中的每个行,都会从此表中读取多行,则使用 ref。 如果使用的键仅匹配几行,则这是一个很好的联接类型。

      ref 可用于使用 = 或 <=> 运算符进行比较的索引列。在以下示例中,MySQL 可以使用 ref join 来处理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;
    • fulltext

      连接使用的是fulltext索引

    • 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;
    • Index_merge

      索引合并多组节点的数据,生成多组节点的并集、交集等,这个方法只能合并单个表中索引的结果集。

      SELECT * FROM tbl_name WHERE key1 = 10 OR key2 = 20;

      SELECT * FROM tbl_name
      WHERE (key1 = 10 OR key2 = 20) AND non_key = 30;

      SELECT * FROM t1, t2
      WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%')
      AND t2.key1 = t1.some_col;

      SELECT * FROM t1, t2
      WHERE t1.key1 = 1
      AND (t2.key1 = t1.some_col OR t2.key2 = t1.some_col2);
    • unique_subquery

      此类型将使用eq_ref替换以下形式的in子查询

      value IN (SELECT primary_key FROM single_table WHERE some_expr)

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

    • index_subquery

      它与unique_subquery的区别是,它适用于子查询中的非唯一索引

    • 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);

    • index

      index连接类型与ALL相同,只是扫描索引树

      • 覆盖索引
      • 按照索引顺序查找数据行
    • All

      针对关联表中每行数据进行全表扫描

  • Extra

    输出Mysql解析sql的额外详细信息。