概述
explain 是 sql 优化的利器,除了优化慢 sql,平时的 sql 编写,也应该先 explain,查看一下执行计划,看看是否还有优化的空间。
直接在 select 语句之前增加 explain 关键字,就会返回执行计划的信息
字段说明
- id 列:MySQL 会为每个 select 语句分配一个唯一的 id 值
- select_type 列,查询的类型,根据关联、union、子查询等等分类,常见的查询类型有 SIMPLE、PRIMARY。
- table 列:表示 explain 的一行正在访问哪个表。
- type 列:最重要的列之一。表示关联类型或访问类型,即 MySQL 决定如何查找表中的行。性能从最优到最差分别为:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
- **:当表仅有一行记录时(系统表),数据量很少,往往不需要进行磁盘 IO,速度非常快
- **:表示查询时命中 primary key 主键或者 unique 唯一索引,或者被连接的部分是一个常量(const)值。这类扫描效率极高,返回数据量少,速度非常快。
- **:查询时命中主键 primary key 或者 unique key 索引, type 就是 eq_ref。
- **:这种连接类型类似于 ref,区别在于 MySQL 会额外搜索包含 NULL 值的行。
- **:使用了索引合并优化方法,查询使用了两个以上的索引。
- unique_subqueryunique_subquery:替换下面的 IN 子查询,子查询返回不重复的集合。
- index_subqueryindex_subquery:区别于 unique_subquery,用于非唯一索引,可以返回重复值。
- **:使用索引选择行,仅检索给定范围内的行。简单点说就是针对一个有索引的字段,给定范围检索数据。在 where 语句中使用 bettween…and、<、>、<=、in 等条件查询 type 都是 range。
- **:Index 与 ALL 其实都是读全表,区别在于 index 是遍历索引树读取,而 ALL 是从硬盘中读取。
- ALL 就不用多说了,全表扫描。
- possible_keys 列:显示查询可能使用哪些索引来查找,使用索引优化 sql 的时候比较重要。
- key 列:这一列显示 mysql 实际采用哪个索引来优化对该表的访问,判断索引是否失效的时候常用。
- key_len 列:显示了 MySQL 使用
- ref 列:ref 列展示的就是与索引列作等值匹配的值,常见的有:const(常量),func,NULL,字段名。
- rows 列:这也是一个重要的字段,MySQL 查询优化器根据统计信息,估算 SQL 要查到结果集需要扫描读取的数据行数,这个值非常直观显示 SQL 的效率好坏,原则上 rows 越少越好。
- Extra 列:显示不适合在其它列的额外信息,虽然叫额外,但是也有一些重要的信息:
- Using index:表示 MySQL 将使用覆盖索引,以避免回表
- Using where:表示会在存储引擎检索之后再进行过滤
- Using temporary :表示对查询结果排序时会使用一个临时表。