explain详解
查询sql查询的执行计划,查看sql查询的索引策略
explain使用
EXPLAIN SELECT * FROM film_actor WHERE film_id = 1;
image-20210311132332668
explain字段
id列
select查询的序号,标记着select查询的顺序
- id相同,由上到下依次执行
- id不同,值越大优先级越高,越先执行
- id为null,最后执行
select_type列
查询中每个select子句的类型(简单或复杂)
- simple:简单类型,不包含子查询和union
- primary:复杂查询的最外面一层select查询
- subquery:包含在select中的子查询(不在from子句中)
- derived:from子句中的子查询,mysql会生成一个临时派生表
EXPLAIN SELECT (SELECT 1 FROM actor WHERE id = 1) FROM (SELECT * FROM film WHERE id = 1) der;
image-20210311132252023
- union:union之后的select查询类型
EXPLAIN SELECT 1 UNION SELECT 1 from (SELECT id FROM actor) a UNION SELECT 3
image-20210311132136191
table列
explain的一行子查询正在访问的表名
当From后有子查询时,子查询为派生的临时表,表名为<deriver+id>值【deriver3】
当有union时,select_type为union_result的table列值为<union1,2,4>,表示行id为1、2、4的子句参与了union
type列
访问类型,表示访问类型,标识着查找行的大概范围
依次从最优到最差分别为:NULL > system > const > eq_ref > ref > range > index > ALL
一般得保证达到range或者ref级别
-
NULL:表示执行过程中不需要访问索引或者表就能得到结果
-
const :根据主键id或唯一索引查询最多只有一条记录
-
system:const的一个变种,查询的表中只有一条记录
-
eq_ref:根据主键id或唯一索引进行关联查询
-
ref:使用普通索引或唯一索引的部分索引关联查询
-
range:范围查找,between、in、>、<、>=、<=等,检索出给定范围的行
-
index:全索引扫描
-
ALL:未使用索引,全表扫描
possible_keys列
可能用到的索引key列表,但不一定使用到。如果值为NULL,则代表该查看语句没有可使用的索引
key列
查询中实际使用的索引,如果值为NULL表示没有使用到索引
key_len列
mysql在索引中使用的字节长度,可以根据字节长度算出来使用到的索引列
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字节
- 如果字段允许为 NULL,需要1字节记录是否为NULL
ref列
显示了在key列中的索引中,表查找值用到的是常量还是字段
const:常量值
test.fa.film_id:test库别名为fa表的film_id字段
rows列
MySQL预估检索的行数,并不是结果集的真实行数
Extra列
扩展额外的信息列
- Using index:使用了覆盖索引(覆盖索引:查询列要被所建的索引覆盖。索引的字段不只包含查询列,还包含查询条件、排序等。)
EXPLAIN SELECT film_id, actor_id FROM film_actor WHERE film_id = 1;
image-20210311145321591
- Using where:
- Using index condition:
- Using temporary:使用临时表,需要优化
- Using filesort:使用外部排序,而非索引排序
- Select tables optimized away:使用聚合函数访问索引字段
网友评论