MySQL的EXPLAIN其实很简单

EXPLAIN命令是查看查询优化器如何决定执行查询的主要方法,使用起来也非常简单,只需在SELECT(同样适用DELETE、UPDATE,本质还是SELECT)语句前加上EXPLAIN关键字即可,MySQL会返回关于在执行计划中的每一步的信息。

创建两个表用来测试验证下,product_category,product_info商品类目表和商品信息表。

----

先来看一个简单的示例:

explain select t.* from product_info t where t.product_id = 122;

返回如下信息:

MySQL的EXPLAIN其实很简单

1. id列

MySQL的查询可以分为简单类型和复杂类型,复杂类型又分为简单子查询,派生表(FROM子句中的子查询),UNION查询。如果只是一个简单查询,那id就会显示1,如果包含子查询,id会顺序编号。通常子查询中,id值大的优先执行。id相同的由上至下执行。

注意id值要结合具体sql语句,不能只看大小,例如:

explain select t.*,(select c.category_name from product_category c where c.category_type = t.category_type) from product_info t where t.product_id = 122;

结果如下:

MySQL的EXPLAIN其实很简单

子查询是DEPENDENT SUBQUERY,要依赖于主查询,所以执行顺序还是先执行id为1的查询,然后再执行id为2的查询。

----

2. select type列

此列展示了对应的row是简单查询还是复杂查询,常见的取值包含:

SIMPLE:不包含子查询和UNION

PRIMARY:外层查询

SUBQUERY:子查询

DEPENDENT SUBQUERY :依赖于外层查询的子查询

DERIVED:派生表查询

----

3. type列

(table和partitions表明正在访问的表和表分区,略过吧),type是访问类型,表明MySQL决定如何查找表中的行。取值包含如下(性能由差到好):

all:最差的全表扫描

index:a.跟全表一样,只是扫描时按索引次序进行而不是行,主要优点是避免了排序,但全表扫描依旧开销很大。b.如果在Extra出现"Using index"时,说明正在使用覆盖索引,只扫描索引的数据,开销相对全字段小很多。

比较两个简单的示例:

explain select t.product_name from product_info t order by t.product_id;

MySQL的EXPLAIN其实很简单

type是index,还是全表扫描。

explain select t.product_id from product_info t;

MySQL的EXPLAIN其实很简单

type是index,Extra是"Using index",只需扫描索引数据。

range:范围扫描,只检索给定范围内的行,当使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN、LIKE或IN()运算符将字段列与常量进行比较时,可以使用Range。

例如:

explain select t.product_id from product_info t where t.product_id between 1000 and 2000;

MySQL的EXPLAIN其实很简单

ref:ref可用于使用=或<=>运算符进行比较的索引列,可以简单理解为使用了非主键、非唯一的索引。

例如,某个经常出现在条件查询的字段需要填加索引,但这个列值并不唯一。

explain select * from product_category c where c.category_name = '电器3C'

MySQL的EXPLAIN其实很简单

eq_ref:可以简单理解为走主键索引或唯一索引查找目标行。

const:匹配单行,走主键索引或唯一索引,通常根据主键查询某条记录的详情就是const了。

system:只有一行记录的表,属于const的特例,略过吧。

----

4 rows和filtered列

rows是MySQL评估为了找到所需的行而要读取的行数,可能不是很精准,读取的行数当然越小越好了。filtered是用来评估根据查询条件过滤数据的百分比,最大是100,这个也是越小越好了。rows × filtered就是可能用到的行数了。

----

5 possible_keys列

这一列罗列出查询可以使用哪些索引,是在优化过程早起创建的,可能对于后续优化过程并无用处。

----

6 key列

key就是索引了,显示可以走哪一个索引可以最小化查询成本。

----

7 key_len列

此列显示了索引字段使用的字节数,即索引字段最大可能的长度,并非实际长度。不过也差不多,毕竟数据表字段大小是按需设计的。显然字段过长的值并不适合用作索引。例如,把一些诸如个人简介、文章内容类的字段建立索引是不恰当的。


上一篇:mysql 索引优化


下一篇:[MySQL] 利用explain查看sql语句中使用的哪个索引