为什么使用explain执行计划
通过EXPLAIN我们可以模拟优化器执行SQL查询语句的过程。通过这种方式分析语句或表的性能瓶颈。使用于SELECT语句
如执行完EXPLAIN SELECT * from course;语句后会得到下面这个形式
通过对这个图中的信息进行分析,从而去优化sql语句。
1、id
定义:查询序列编号,一个select有一个编号
id值相同时,从上往下查询;id值不同时,从大到小查询。
2、select_type
查询类型
SIMPLE:简单的SELECT语句(不包括UNION操作或子查询操作)
PRIMARY:子查询语句中的主查询,也就是最外层的查询(即第一个select)
SUBQUERY:子查询语句中的内层查询(即除了最外层select)
DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询 。(子查询依赖于外层查询,要注意这是浪费时间的)
DERIVED:用于 from 子句里有子查询的情况。
下面的是基于UNION操作的:
UNION:UNION操作中,查询中处于内层的SELECT(内层的SELECT语句与外层的SELECT语句没有依赖关系)
DEPENDENT UNION:UNION操作中,查询中处于内层的SELECT(内层的SELECT语句与外层的SELECT语句有依赖关系)
UNION RESULT:UNION操作的结果,id值通常为NULL
3、table
当前查询所用到的表
4、type
查询类型
type属性从优到最差
system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>all
其中最常用的七种排序:
system > const > eq_ref > ref > range > index > ALL
以上类型除了ALL都可以使用索引
一般来说,得保证查询至少达到range级别,最好能达到ref。
- system :表只有一行记录(等于系统表),这是const类型的特列,平时不会出现
- const :主键索引或者唯一索引与常数进行等值匹配,只能查询到一条数据。因为只匹配一行数据,所以很快
- eq_ref :唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配,常见于主键或唯一索引扫描
- ref :非唯一性索引扫描,返回匹配某个单独值的行,它可能会找到多个符合条件的行,与eq_ref相比,里面的数据可以重复。
- range: 对索引进行范围查询,一般就是在你的where语句中出现了between、<、>、in等的查询
- index : Full Index Scan,Index与ALL虽然都是读全表,但index是从索引树中读取。
- ALL: Full Table Scan,遍历全表以找到匹配的行。(慢)
5、possible_keys
可能用到的索引
6、key
实际用的索引
7、key_len
索引的长度(字节数),跟索引的类型和长度有关
如:
utf8mb4编码下 varchar类型的索引长度:
utf8mb4一个字符占四个字节,变成字段额外需要两个字节,允许为空需要1个字节
8、ref
显示索引的哪一列被使用了,如果可能的话是一个常数(const),哪些列或常量被用于查找索引列上的值
9、rows
MySQL认为需要扫描多少行(数据或索引)才可以返回数据,是一个预估值,一般来说越少越好。
10、Extra
执行计划给出的额外信息
- Using filesort:不是使用索引排序,用到了额外的排序。(需要优化)
- Using temporary:在查询的时候,需要做去重、排序之类的工作时,可能会用到临时表(需要优化,如建立复合索引)
- Using index:使用了覆盖索引,不需要回表
- Using where:使用了where过滤,表示存储引擎返回的记录并不是所有都满足查询条件,需要在server层过滤
- Using Index Condition:索引下推
- Using join buffer: 表明使用了连接缓存,如在查询的时候会有多次join,则可能会产生临时表
- impossible where:表示where子句的值总是false,不能用来获取任何元祖。
参考博客
https://blog.youkuaiyun.com/tangdaren2/article/details/107491101
https://www.cnblogs.com/myseries/p/10736268.html