Explain Output Format 8.0(mysql执行计划)
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开始自增,执行顺序如下
- id相同,自上而下
- id不同,从大到小执行
- 如果显示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的额外详细信息。