MySQL Explain机制!
MySQL Explain机制!
月伴飞鱼table列:
表示 explain 的一行正在访问哪个表。
当 from 子句中有子查询时,table列是
<derivenN>
格式:
- 表示当前查询依赖 id=N 的查询,先执行 id=N 的查询。
- 当有 union 时,UNION RESULT 的 table 列的值为
<union1,2>
,1和2表示参与 union 的 select 行id。
id列:
id列的编号是 select 的序列号,有几个 select 就有几个id,并且id的顺序是按 select 出现的顺序增长的。
- id列越大执行优先级越高,id相同则从上往下执行,id为NULL最后执行。
select_type列:
SIMPLE:
- 查询语句中不包含UNION或者子查询的查询都算作是SIMPLE类型。
PRIMARY:
- 对于包含UNION、UNION ALL或者子查询的大查询来说,它是由几个小查询组成。
- 其中最左边的那个查询的
select_type
值就是PRIMARY。
type列:
从最优到最差分别为:
system > const > eq_ref > ref > range > index > ALL
。
- 一般来说,得保证查询达到range级别,最好达到ref。
eq_ref:
primary key
或unique key
索引使用,最多只会返回一条符合条件的记录。ref:
- 当通过普通二级索引来查询某个表,那么对该表的访问方法就可能是ref。
- 相比
eq_ref
,不使用唯一索引,可能会找到多个符合条件的行。ref_or_null:
- 当对普通二级索引查询,该索引列的值可以是NULL值时,那么对该表的访问方法就可能是
ref_or_null
range:
- 范围扫描通常出现在
in(), between ,> ,<, >=
等操作中。- 使用一个索引来检索给定范围的行。
index:
- 当使用索引覆盖,但需要扫描全部的索引记录时,该表的访问方法就是index。
index_merge:
- 一般情况下对于某个表的查询只能使用到一个索引,但在某些场景下可以使用多种索引合并的方式来执行查询。
ALL:
- 全表扫描。
possible_keys列:
显示查询可能使用哪些索引来查找。
key_len列:
显示了索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列。
key_len计算规则如下:
字符串:
- char(n):n字节,varchar(n):2字节,如果是utf-8,则长度 3n + 2
数值类型:
- tinyint:1字节,smallint:2字节,int:4字节,bigint:8字节
时间类型:
- date:3字节,timestamp:4字节,datetime:8字节
rows列:
读取并检测的行数,注意这个不是结果集里的行数。
如果使用全表扫描查询时,执行计划的rows列就代表预计需要扫描的行数。
如果使用索引查询时,执行计划的rows列就代表预计扫描的索引记录行数。
ref列:
显示了在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量),字段名。
- ref列展示的就是与索引列作等值匹配的值什么,比如只是一个常数或者是某个列。
Extra列:
Using index
- 查询的列被索引覆盖,并且where筛选条件是索引的前导列。
- 一般是使用了覆盖索引(索引包含了所有查询的字段)。
Using where
- 使用全表扫描来执行对某个表的查询,并且该语句的WHERE子句中有针对该表的搜索条件时。
Using where Using index
- 查询的列被索引覆盖,并且where筛选条件是索引列之一但是不是索引的前导列。
- 意味着无法直接通过索引查找来查询到符合条件的数据。
Using index condition
- 查询的列不完全被索引覆盖,where条件中是一个前导列的范围。
Using temporary
- 在执行DISTINCT、GROUP BY、UNION等子句的查询时。
- 如果不能利用索引来完成查询,MySQL通过建立内部的临时表来执行查询。
Using filesort
- 会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。
MySQL EXPLAIN 扫描行数准确吗?
EXPLAIN
的结果会包含rows
列,它表示SQL 预计扫描的行数,但这只是估算值。如果想获取实际扫描的行数,需要使用
EXPLAIN ANALYZE
。
1 | EXPLAIN ANALYZE SELECT * FROM your_table WHERE some_column = 'value'; |
在 MySQL 8.0 及以上版本,这个命令会真正执行查询,并提供实际扫描的行数。
通常在
analyze
输出的rows_examined
字段中可以看到。