mysql explain用法和结果分析

explain简介:
使用explain关键字可以模拟优化器执行sql查询语句,从而知道mysql是如何处理你的sql语句。
使用方式如下:explain sql。
执行计划包含的信息:

+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table    | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+

执行计划各字段含义:
1:id:select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序。
id的结果共有三种情况:
1.1:id相同,执行顺序由上而下。
在这里插入图片描述
上图中的table列表示加载表的顺序:t1、t2、t3。

1.2:id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行。
在这里插入图片描述
1.3:id相同、不同同时存在。
在这里插入图片描述
如上图所示,在id为1时,table显示的是 ,这里指的是指向id为2的表,即t3表的衍生表。

2:select_type:用来表示查询的类型,主要是用于区别普通查询、联合查询、子查询等的复杂查询。
常见和常用的值有以下几种:
在这里插入图片描述
simple:简单的select查询,查询中不包含子查询或者union。

explain select * from sdb_b2c_orders left join sdb_b2c_order_items on sdb_b2c_orders.order_id=sdb_b2c_order_items.order_id where sdb_b2c_orders.order_id=20191018149974

在这里插入图片描述
primary:查询中若包含任何复杂的子查询,最外层查询会被标记为primary。
subquery:在select或where列表中包含了子查询。

explain select * from sdb_b2c_orders where member_id = (select member_id from sdb_b2c_members where mobile=18202139749)

在这里插入图片描述
DERIVED:在FROM列表中包含的子查询被标记为DERIVED(衍生),MySQL会递归执行这些子查询,把结果放在临时表中。
UNION:若第二个SELECT出现在UNION之后,则被标记为UNION:若UNION包含在FROM子句的子查询中,外层SELECT将被标记为:DERIVED。
UNION RESULT:从UNION表获取结果的SELECT。

3:table:指的是当前执行的表。

4:type:对表的访问方式,表示mysql在表中找到所需行的方式,又称访问类型。
常用的类型有: ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)
All:mysql将遍历全表以找到匹配的行。
index:index与All的区别为index类型只遍历索引树。这通常比ALL快,因为索引文件通常比数据文件小,而且索引数据一般情况下会保存在内存里。
range:只检索给定范围的行,使用一个索引来选择行,key列显示使用了哪个索引,一般就是在你的where语句中出现between、<、>、in等的查询,这种范围扫描索引要比全索引扫描性能要好,因为它只需要开始与索引的某一点,而结束与另一点,不用扫描全部索引。
在这里插入图片描述
index_merge:在查询过程中需要多个索引组合使用,通常出现在有or关键字的sql语句中。

explain select member_id from sdb_b2c_members where mobile = '18202139749' or name = '姆巴佩';

在这里插入图片描述

ref:非唯一性索引扫描,返回匹配某个单独值的所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体。

select * from student3;
+----+------+-----+--------+--------+
| id | name | age | height | weight |
+----+------+-----+--------+--------+
|  1 | lbj  |  20 |    203 |    220 |
|  2 | lbj  |  20 |    203 |    220 |
|  3 | lbj  |  20 |    203 |    220 |
+----+------+-----+--------+--------+
3 rows in set (0.00 sec)

mysql>
mysql> explain select * from student3 where name='lbj';
+----+-------------+----------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table    | partitions | type | possible_keys | key     | key_len | ref   | rows | filtered | Extra       |
+----+-------------+----------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | student3 | NULL       | ref  | n_a_h_w       | n_a_h_w | 32      | const |    3 |   100.00 | Using index |
+----+-------------+----------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配,常见于主键索引或唯一索引。

const:表示通过索引一次就找到了,const用于比较primary key 或者unique索引。因为只匹配一行数据,所以很快。如将主键置于where列表中,MySQL就能将该查询转换为一个常量。
在这里插入图片描述
首先进行子查询得到一个结果的d1临时表,子查询条件为id = 1 是常量,所以type是const,id为1的相当于只查询一条记录,所以type为system。

system 表只有一行记录(等于系统表),这是const类型的特列,平时不会出现,这个也可以忽略不计

5:possible_keys:显示可能应用在这张表中的索引,一个或多个,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用。

6:key:实际使用的索引,如果为null,则没有使用到索引。(可能原因包括没有建立索引,或索引失效)。
在这里插入图片描述
查询中若使用了覆盖索引(select后要查询的字段刚好和创建的索引字段完全相同),则该索引仅出现在key列表中。

explain select name from student3;   name字段建了索引。
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table    | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra       |
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | student3 | NULL       | index | NULL          | n_a_h_w | 44      | NULL |    4 |   100.00 | Using index |
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

7:key_len:表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度,在不损失精确性的情况下,长度越短越好。key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的。
key_len详细介绍

8:ref:显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或常量被用于查找索引列上的值

9:rows:根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数,也就是说,用的越少越好

10:extra:该列包含mysql解决查询的详细信息,有以下几种情况。
Using where:不用读取表中所有信息,仅通过索引就可以获取所需数据,这发生在对表的全部的请求列都是同一个索引的部分的时候,表示mysql服务器将在存储引擎检索行后再进行过滤
Using temporary(十死无生):使用了用临时表保存中间结果,MySQL在对查询结果排序时使用临时表。常见于排序order by和分组查询group by。
在这里插入图片描述
Using filesort(九死一生):当Query中包含 order by 操作,而且无法利用索引完成的排序操作称为“文件排序”。说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL中无法利用索引完成的排序操作称为“文件排序”。
在这里插入图片描述
Using index(发财了):表示相应的select操作中使用了覆盖索引(Covering Index),避免访问了表的数据行,效率不错。如果同时出现using where,表明索引被用来执行索引键值的查找;如果没有同时出现using where,表明索引用来读取数据而非执行查找动作。
在这里插入图片描述
在这里插入图片描述
Using join buffer:
表明使用了连接缓存,比如说在查询的时候,多表join的次数非常多,那么将配置文件中的缓冲区的join buffer调大一些。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章