使用EXPLAIN可以查看查询语句的执行计划,分析这个语句的性能瓶颈。
示例:
explain select * from actor;
id
查询语句执行顺序,值越大越先执行;值相等从上向下执行;值为 NULL,最后执行。
select_type
表示这个查询是简单查询还是复杂查询。
- SIMPLE:简单查询,不包含子查询和 union。
- PRIMARY:复杂查询最外面的那层查询。
- SUBQUERY:select 后面跟着的子查询。
- DERIVED:from 后面跟着的子查询。
table
查询的表名。
partitions
如果查询是基于分区表的话,partitions 会显示查询将要访问的分区。
type
表示关联类型或访问类型,及 MySQL 决定如何查找表中的行。
- NULL:MySQL 优化后的查询语句可以不访问表,例如寻找最小值。
- system:system 是 const 的特例,表中只有一条数据时为 system。
- const:查询条件是 primary key 或 unique key 对应的字段,根据这个字段只能查出来一条数据。
- eq_ref:主键索引或唯一索引的所有部分被连接使用。
- ref:使用了普通索引或唯一性的索引部分前缀。
- range:范围查找,在 in(), between, >, <, >= 等范围查询过程中,对应的字段带有索引。
- index:直接遍历二级索引的叶子节点,当出现这个标志说明这个条语句需要优化。
- all:遍历聚簇索引的叶子节点,当出现这个标志说明这个条语句需要优化。
possible_keys
可能会使用的索引,不一定会使用。
key
查询过程中使用的索引。
key_len
通过这个值,可以计算出使用了联合索引的哪些字段。
计算规则(字节数)
- 字符串类型(utf8)
- char(n):3*n
- varchar(n):3*n+2,2是表示存储的字符串长度,因为 varchar 是变长字符串
- 数值类型
- tinyint:1
- smallint: 2
- int: 4
- bigint:8
- char(n):3*n
- 时间类型
- date:3
- timestamp:4
- datetime:8
- date:3
ref:在查询中用到了 key 列的索引哪些字段或者常量(const)。
rows:MySQL 估计要读取检测的行数,不是真实读取的行数。
filtered:利用 rows * filtered / 100 可以计算出当前表和 explain 中前一张表(id-1) 进行连接的行数。
extra:额外的信息。
- Using index:使用了覆盖索引,即查询字段与索引字段完全相同,只在二级索引查询就可以。
- Using where:没有使用索引。
- Using index condition:索引字段没有完全覆盖查询字段。
- Using temporary:使用了临时表,需要增加索引优化。
- Using filesort:排序的时候没有使用索引,数据量少的时候在内存排序,否则就要在磁盘排序,这个需要增加索引进行优化。
- Select tables optimized away:使用了聚合函数访问了索引的某个字段。
Using filesort 的排序方式
单路排序:根据查询条件,一次性取出满足条件的每行的所有字段,放入 sort buffer(MySQL 的排序内存) 中,在 sort buffer 中根据 order by 字段进行排序。
双路排序:根据查询条件,只取出要排序的字段和主键 id, 把这些字段放入 sort buffer 中进行排序,排序后再根据主键 id 回表查询全部数据。