mysql执行计划
Published on: | Views: 91在优化mysql执行速度的时候, 执行计划是非常重要的, 通过执行计划可以知道语句慢在哪里, 从而针对性地优化语句.
mysql中, 执行计划是通过explain 命令查看, 加到查询语句前面就可以了, 详细的官方文档见: https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
explain 支持的查询命令包括: select, insert , update, delete, replace.
语法
explain 可以查看表的定义,但这里我们只考虑查询计划:
explainable_stmt: {
SELECT statement
| DELETE statement
| INSERT statement
| REPLACE statement
| UPDATE statement
}
# 结果查看 建立三个表来做示例 student(id,name) class(id,name) student_class(id,class_id,student_id)
试着执行一下:
explain select * from student_class sc
join class c on sc.class_id = c.id
join student s on sc.student_id = s.id;
一般mysql是通过NLJ(Nested-Loop Join)或者BNLJ(Block Nested-Loop Join)来处理join请求,NLJ算法是这样的,例如一个执行计划如下:
Table Join Type
t1 range
t2 ref
t3 ALL
查询处理如下:
for each row in t1 matching range {
for each row in t2 matching reference key {
for each row in t3 {
if row satisfies join conditions, send to client
}
}
}
它是在第一个表中读了一行,然后再读第二个表匹配的行。。。直到读取最后一个表, 一条查询结果就出来了, 接着再读第一个表的第二行,如此循环,直到查询出所有结果, 属于深度搜索算法。 BNLJ增加了一个join buffer的缓存,把外层循环的数据缓存成块后,再执行内部循环,加快速度。
执行计划会输出很多列,这些列定义如下:
id
查询号,每个id代表一个查询。 相同id的行,属于同一个查询,从上到下依次是最外层循环,次外层。。。最里层循环。 如果行引用的是union结果时,这个行的id列是空的。
select_type
这个类型是查询类型,其取值如下:
- SIMPLE: 查询中不包括union和子查询
- PRIMARY: 最外层的查询
- UNION: union第二条或者后续语句
- DEPENDENT UNION: union第二条或者后续语句,并且依赖外层查询结果
- UNION RESULT:依赖union结果
- SUBQUERY:子查询
- DEPENDENT SUBQUERY: 子查询,并且依赖外层查询结果
- DERIVED: 派生查询
- MATERIALIZED:物化子查询
- UNCACHEABLE SUBQUERY: 无法缓存的子查询
- UNCACHEABLE UNION: 无法缓存的union
table
本行对应的表名,也可以是:
partitions
分区号,如果表分了区的话。
type
这个类型是访问类型, 其取值如下: - system:表中只有一行(系统表) - const: 表中最多匹配到一行, 使用主键或者唯一键与常量比较(=) - eq_ref:表中最多只匹配到一行, 使用表的主键或者非空唯一键与查询结果比较(=) - ref: 表中会匹配到多行,使用表的普通索引与查询结果比较(=,<=>) - fulltext: 使用表的fulltext索引进行比较 - ref_or_null: 和ref一样,只是多了一步使用key和null比较(is null) - index_merge: 表示使用索引合并优化 - unique_subquery:和eq_ref类似, 但是是使用 IN(子查询)的比较方式 - index_subquery: 和ref类似,但是是使用 IN(子查询)的比较方式 - range: 使用表的普通索引和常量比较(=, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, LIKE, IN) - index: 有两种情况,一是查询的数据全部在索引中(Extra data会有use index), 二是以索引的顺序来进行全表扫描 - all: 全表扫描
possible_keys
可能用到的索引
key
实际使用的索引
key_len
实际用到的索引长度
ref
索引的比较对象,来自于上一层的表
rows
检查的行数
filtered
过滤百分比, 返回行数/检查行数
Extra
额外信息 using index: 数据全部在索引中,将会使用覆盖索引 using where: 使用where进行条件过滤,当条件在索引中时,存储引擎就可以过滤。 using temporary: 对结果排序时使用临时表 using filesort: 使用外部排序,而不是索引排序