前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL中explain中的结果字段介绍(三)

MySQL中explain中的结果字段介绍(三)

作者头像
AsiaYe
发布2019-11-06 17:46:15
2.1K0
发布2019-11-06 17:46:15
举报
文章被收录于专栏:DBA随笔DBA随笔
MySQL中explain中的结果字段介绍(三)

之前的文章中对于explain的数据结果中的字段已经进行了一部分介绍了,今天来说一说剩下的几个字段,为了防止忘记,先看看这个表结构:

代码语言:javascript
复制
mysql--dba_admin@127.0.0.1:yeyztest 21:13:04>>show create table test_explain\G
*************************** 1. row ***************************
       Table: test_explain
Create Table: CREATE TABLE `test_explain` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a_key_var` varchar(100) DEFAULT NULL,
  `b_key_int` int(11) DEFAULT NULL,
  `c_key_var` varchar(100) DEFAULT NULL,
  `d_key_var1` varchar(100) DEFAULT NULL,
  `d_key_var2` varchar(100) DEFAULT NULL,
  `d_key_var3` varchar(100) DEFAULT NULL,
  `e_normal_var` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_key_b` (`b_key_int`),
  KEY `idx_key_a` (`a_key_var`),
  KEY `idx_key_c` (`c_key_var`),
  KEY `idx_key_d` (`d_key_var1`,`d_key_var2`,`d_key_var3`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

先来看看最后几个字段是什么:

代码语言:javascript
复制
mysql:yeyztest 21:13:15>>explain select * from test_explain where id=2;
+----+-------------+--------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table        | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
+----+-------------+--------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test_explain | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+--------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

可以看到,分别是key_len,ref,rows,filtered以及extra这5个字段。下面我们介绍以下这5个字段的意思:

key_len

key_len表示当优化器制定某个列作为索引的时候,这个索引记录的最大长度,这里需要注意的是,这个最大长度的单位为字节,一般来讲,最大长度由以下三个因素决定:

1、如果该字段是固定长度的类型,例如char类型的,那么它实际占用存储空间的最大长度就是这个固定值。如果是varchar这种变长类型的,那么它的最大长度就是变长类型定义中的长度,比如对于varchar(20),采用utf8编码,最大长度就是20*3=60字节

2、如果索引列中可能包含null值,那么会额外占用1个字节

3、对于varchar这种变长字段,需要有额外的2个字节来保存长度

有了这三条规则,就能比较容易理解key_len的值了,例如上面的例子中,key_len的值是4,它的原因是int类型是固定长度,一个int是4个字节大小

再来看下面这个查询:

代码语言:javascript
复制
mysql:yeyztest 21:14:46>>explain select * from test_explain where a_key_var='a';
+----+-------------+--------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
| id | select_type | table        | partitions | type | possible_keys | key       | key_len | ref   | rows | filtered | Extra |
+----+-------------+--------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test_explain | NULL       | ref  | idx_key_a     | idx_key_a | 303     | const |    1 |   100.00 | NULL  |
+----+-------------+--------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

查询的字段是a_key_var,这个字段的类型是varchar(100),那么key_len真实的长度就是100*3+1+2,也就是303了。目前,我们这个字段a_key_var是可以为null值的,如果我们改成不能为null值,如下,可以看到key_len的值发生了变化,变成了302,这就说明了null值是占用了一个字节。

代码语言:javascript
复制
mysql:yeyztest 21:30:40>>alter table test_explain modify a_key_var varchar(100) not null default '';
Query OK, 9 rows affected (0.03 sec)
Records: 9  Duplicates: 0  Warnings: 0

mysql:yeyztest 22:15:09>>explain select * from test_explain where a_key_var='a';
+----+-------------+--------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
| id | select_type | table        | partitions | type | possible_keys | key       | key_len | ref   | rows | filtered | Extra |
+----+-------------+--------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test_explain | NULL       | ref  | idx_key_a     | idx_key_a | 302     | const |    1 |   100.00 | NULL  |
+----+-------------+--------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

ref

ref的值就是指在进行条件过滤的时候,与条件匹配的值是一个常数还是一个变量之类的,我们可以看到,上面的结果中,ref字段的值都是const,是因为我们使用常量a或者常量2和索引字段进行匹配,如果我们使用某个字段进行匹配,来看下面:

代码语言:javascript
复制
mysql:yeyztest 22:24:42>>explain select * from test_explain t1 inner join test2 t2 where t1.id=t2.id;
+----+-------------+-------+------------+--------+---------------+-----------+---------+----------------+------+----------+-------------+
| id | select_type | table | partitions | type   | possible_keys | key       | key_len | ref            | rows | filtered | Extra       |
+----+-------------+-------+------------+--------+---------------+-----------+---------+----------------+------+----------+-------------+
|  1 | SIMPLE      | t2    | NULL       | index  | PRIMARY       | idx_birth | 6       | NULL           |    1 |   100.00 | Using index |
|  1 | SIMPLE      | t1    | NULL       | eq_ref | PRIMARY       | PRIMARY   | 4       | yeyztest.t2.id |    1 |   100.00 | NULL        |
+----+-------------+-------+------------+--------+---------------+-----------+---------+----------------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)

这个例子中ref的值是yeyztest.t2.id,说明是t1的主键和这个id去做的匹配。

rows

rows代表的是执行计划预计扫描的索引记录行数。上面的例子中,我们可以看到,预计将会扫描的记录数为1条,但是需要注意的是,这个值是个预计值,而不能被看做真实值。

filter

这个值代表的是根据某个索引查询到记录数之后,大约有多少比例的记录匹配剩余的条件。也就是说,比如我们某个表的主键是id,过滤条件是id>4 and age<30,假设id>4的记录数预计为40条,也就是explain中的rows的记录为40,那么filter的意思就是在这40条记录里面,大概有多少比率的记录符合age<30.如下:

代码语言:javascript
复制
mysql:yeyztest 22:40:36>>explain select * from test_1 where id>=4 and age<30;
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table  | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra       |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | test_1 | NULL       | range | PRIMARY       | PRIMARY | 4       | NULL |   40 |    33.33 | Using where |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

Extra

这个字段主要还是提供一些查询的额外信息,可能出现的情况比较多,这里列出来常用的一些即可,就不进行举例说明了。

Using where 表示Mysql将对storage engine提取的结果进行过滤,过滤条件字段无索引;

Using temporary 要解决查询,MySQL需要创建一个临时表来保存结果。如果查询包含不同列的GROUP BY和ORDER BY子句,则通常会发生这种情况

Using index 仅使用索引树中的信息从表中检索列信息,而不需要进行回表来读取实际行

Using index condition Using index condition 会先条件过滤索引,过滤完索引后找到所有符合索引条件的数据行,随后用 WHERE 子句中的其他条件去过滤这些数据行;

Using filesort 当Query 中包含 ORDER BY 操作,而且无法利用索引完成排序操作的时候,MySQL Query Optimizer 不得不选择相应的排序算法来实现。数据较少时从内存排序,否则从磁盘排序

no matching ... && not exist

找不到匹配的记录。

Using join buffer

这种情况主要发生在join的连接查询中,将外层循环的行/结果集存入join buffer, 内层循环的每一行与整个buffer中的记录做比较,从而减少内层循环的次数

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DBA随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档