EXPLAIN的基本介绍
关于MySQL的优化,我们首先要了解explain这个东西。explain能够帮助我们来查看我们所写的SQL的内部执行计划,包括是否使用索引、有没有做全表扫描等等,让我们能更好地了解自己编写的SQL。
我们深入了解MySQL的基于开销的优化器,可以获得很多可能被优化器考虑到的访问策略的细节,以及当我们编写的SQL在何种情况下不会被优化器所采用。
1. explain的用法
explain的用法:在我们要查询的SQL之前加上该关键字,注意要是查询SQL
。
用法如下所示:
EXPLAIN
SELECT * FROM iot_product_discount pd
WHERE pd.`id` = "7b8bab6e4d6c4e6ba4bfcac40349ca33";
2. id
- id相同时,执行顺序由上到下。
- 如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行。
- id如果相同,可以认为是一组,从上往下顺序执行。在所有组中,id值越大,优先级越高。
3.select_type
值 | 解释 |
---|---|
SIMPLE | 简单SELECT,不使用UNION或子查询等 |
PRIMARY | 查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY |
UNION | union语句的第二个或者说是后面的SELECT语句 |
DEPENDDENT UNION | UNION中的第二个或者后面的select语句,取决于外面的查询 |
UNION RESULT | UNION的结果 |
SUBQUERY | 子查询中的第一个SELECT |
DEPENDENT SUBQUERY | 子查询中的第一个select,取决于外面的查询 |
DERIVED | 派生类的SELECT, FROM子句的子查询 |
UNCACHEABLE SUBQUERY | 一个子查询的结果不能被缓存,必须重新评估外链接的第一行 |
- PRIMARY
PRIMARY的解释为:查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY。我们能够看到最id=1的那一行是属于PRIMARY,是查询middle表。 - UNION
PRIMARY的解释为:union语句的第二个或者说是后面的SELECT语句。我们能够看到我们后面连接的一个select表即p2
表select_type属性为UNION。
4.table
该字段显而易见就是哪张表的,有时候不是真实的表名字,有时候是看到的是derivedX
(X是个数字,为第几步执行的结果)。
5.type
type是我们在MySQL中找表所需的方式,又称"访问类型"
。
常用类型从好到差有:
NULL、system、const、eq_ref、ref、range、index、ALL。
- NULL
MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如:从一个索引列里选取最小值可以通过单独索引查找完成。 - system
system这是const类型的特列,当查询的表只有一行的情况下,才会出现。平时不会出现,这个也可以忽略不计。 - const
表最多有一个匹配行,const用于比较primary key 或者 unique索引。因为值匹配一行数据,所以很快。记住一定是用到primary key 或 unique,并且值检索两条数据的情况下才会是const。
虽然只搜索到一条数据,但是因为没有用到指定的索引,所以不会类型不会是const。
这边查到的也是一条数据,但是是使用id主键来检索,所以执行的访问类型为const,可以理解const是最优化的。
-
eq_ref
对于eq_ref的解释,MySQL手册是这样说的:对于每个来自前面的表的组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。它用在一个索引的所有部分被联接使用并且索引是 unique 或者 primary key。
eq_ref可以用于使用=比较带索引的列。
我们能够看到f表
是通过eq_ref来索引的。
相同的两张表,我们只是将其相等的字段进行了替换,我们可以发现因为p.discount 不是索引或主键,所以这时候type就变成了ALL,非eq_ref
。 -
ref
ref对于每个来自前面的表的行组合,所有有匹配的索引值都将从这张表中读取。如果联接只使用键的最左边的前缀,或如果键不是unique或primary key(换句话说,如果联接不能基于选择单个行的话),则使用ref。如果使用的键仅仅匹配少量行,该联接类型还是不错的。 -
index_merge
该联接类型表示使用了索引合并优化方法。在这种情况下,key列包含了使用的索引的清单,key_len包含了使用的索引的最长的关键元素。 -
range
给定范围内的检索,使用一个索引来检查行。
如上图所示,因为p.flow_product_id 既不是索引也不是主键,所以这边显示的type为ALL。
如上图所示,因为p.id 是主键,所以这边显示的type为range。
- index
该联接类型与ALL
相同,除了只有索引树被扫描。这通常比ALL
快,因为索引文件通常比数据文件小。(也就是说虽然all和index都是读全表,但是index是从索引中读取,而all是从硬盘中读取的) - ALL
对于每个来自先前的表的行组合,进行完整的表扫描。如果表是第一个没标记const的表,这通常不太好,而且在通常在它的情况下很差。通过可以增加更多的索引而不要使用ALL,使得行能基于前面的表中的常数值或列值被检索出来。
剩下的属性将在第二篇中介绍