MySQL explain结果Extra中”Using Index”与”Using where; Using index”区别探究[通俗易懂]

MySQL explain结果Extra中”Using Index”与”Using where; Using index”区别探究[通俗易懂]问题背景 最近用explain命令分析查询sql执行计划,时而能看到Extra中显示为"Using index"或者"Using where; Using Index&q

MySQL explain结果Extra中"Using Index"与"Using where; Using index"区别探究

问题背景

最近用explain命令分析查询sql执行计划,时而能看到Extra中显示为”Using index”或者”Using where; Using Index”,对这两者之间的明确区别产生了一些疑惑,于是通过网上搜索、自行实验探究了一番其具体区别。

测试数据准备

以下表作为测试表进行sql分析。

CREATE TABLE `test_table` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `f0` int(11) NOT NULL,
  `f1` varchar(50) NOT NULL,
  `f2` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_f0_f1` (`f0`,`f1`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4

包含以下数据:

INSERT INTO test_table (f0, f1, f2) VALUES (1, "111", 1), (2, "222", 2), (3, "333", 3), (4, "444", 4), (5, "555", 5), (6, "666", 6);

仅有Using where含义

对于仅有Using where的情况,文档中写到:

A WHERE clause is used to restrict which rows to match against the next table or send to the client. Unless you specifically intend to fetch or examine all rows from the table, you may have something wrong in your query if the Extra value is not Using where and the table join type is ALL or index.

第一句话的大意是有一个where子句用于限制返回哪些匹配行到客户端或者下一个表–简单说就是有使用where条件限制要返回的select结果,从这里并没有提出Using where与是否需要回表读完整行数据有任何联系。
如下语句无where条件所以无Using where:

 EXPLAIN SELECT * FROM test_table;
 +----+-------------+------------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table      | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |
+----+-------------+------------+------------+------+---------------+------+---------+------+------+----------+-------+
|  1 | SIMPLE      | test_table | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    6 |   100.00 | NULL  |
+----+-------------+------------+------------+------+---------------+------+---------+------+------+----------+-------+

如下语句使用where子句添加限制,其Extra中有Using where结果:

EXPLAIN SELECT * FROM test_table WHERE f2=3;
+----+-------------+------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table      | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+------------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | test_table | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    6 |    16.67 | Using where |
+----+-------------+------------+------------+------+---------------+------+---------+------+------+----------+-------------+

仅有Using index含义

仅有Using index的情况,文档中写道:

The column information is retrieved from the table using only information in the index tree without having to do an additional seek to read the actual row. This strategy can be used when the query uses only columns that are part of a single index.

即表示where 和select中需要的字段都能够直接通过一个索引字段获取,无需再实际回表查询,当查询涉及的列都是某一单独索引的组成部分时即为此种情况,这实际上就是索引类型中覆盖索引。
如下语句所有查询列均包含在索引中,所以有Using index:

EXPLAIN SELECT f0, f1 FROM test_table WHERE f0=3;
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------------+
| id | select_type | table      | partitions | type | possible_keys | key       | key_len | ref   | rows | filtered | Extra       |
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | test_table | NULL       | ref  | idx_f0_f1     | idx_f0_f1 | 4       | const |    1 |   100.00 | Using index |
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------------+

如下语句虽然where子句涉及列均包含在索引中,但是select中包含额外列,所以无Using index:

EXPLAIN SELECT f0, f1, f2 FROM test_table WHERE f0=3;
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
| id | select_type | table      | partitions | type | possible_keys | key       | key_len | ref   | rows | filtered | Extra |
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test_table | NULL       | ref  | idx_f0_f1     | idx_f0_f1 | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+

同时包含两者:Using where;Using Index的情况

遍寻网上相关资料,总结下来主要有两种看法:

  1. Using index表示使用索引查询初步结果集,如果+Using where表示获取初步结果集后还需进一步根据where子句条件筛选索引条件后返回最终结果集。
  2. Using index表示使用索引查询初步结果集,如果+Using where表示获取初步结果集后还需要回表进一步查询数据再根据where子句条件筛选出最终结果集。

两种看法的分歧点就在于Using where是否表示需要回表查询数据,认为需要回表查数据的文档依据主要基于文档中的下述说明:

Using index
The column information is retrieved from the table using only information in the index tree without having to do an additional seek to read the actual row. This strategy can be used when the query uses only columns that are part of a single index.

If the Extra column also says Using where, it means the index is being used to perform lookups of key values. Without Using where, the optimizer may be reading the index to avoid reading data rows but not using it for lookups. For example, if the index is a covering index for the query, the optimizer may scan it without using it for lookups.

其关键在于第二段中:Without Using where,优化器将可以通过只读索引而避免进一步回表读取完整行数,所以我们正常理解Using where自然就意味着需要去回表读取行数据了。
然而实际上该文档说明来源于dev版MySQL5.1的文档,在5.6及以上版本的文档中已经没有该内容,而我在存档的Mysql5.1 官方文档MySQL 5.1 Reference Manual中也没有找到对应内容,其实际来源暂不可考,这里把讨论范围限于5.6及以上版本。
于是通过上面的Using where与Using Index的官方文档说明可以得出以下三点:

  1. Using where仅表示是否存在where子句限制对结果集进行筛选后返回
  2. Using Index仅表示是否使用了覆盖索引,即查询涉及字段均可以从一个索引中获得,单独的Using Index表示从索引中获取返回结果集即可直接作为最终结果返回。
  3. 出现Using where; Using index 表示sql使用了覆盖索引–所有字段均从一个索引中获取,同时在从索引中查询出初步结果后,还需要使用组成索引的部分字段进一步进行条件筛选,而不是说需要回表获取完整行数据–其实直觉上这种理解也更合理,因为Using index已经表示所有查询涉及字段都在索引里面包含了,压根没有什么额外字段需要再回表才能获取,那回表又有什么意义呢?
    另外,通过一番简单的查找MySQL(Mariadb 10.3)源码,发现以下代码,由于未深入探究源码流程,这里简单猜测其正是用于判定是否添加 Using where的判断代码:
explain->using_where= MY_TEST(select && select->cond);

进一步佐证Using where即表示select包含条件子句。
sample:
如下sql仅涉及索引字段,但是要在where子句中对索引字段f0进行取余计算后才能比较条件,此种情况下无法直接在第一步查找索引时即进行条件判断,只能先把索引全部取出作为初步结果集,而后再进行where子句筛选:

EXPLAIN SELECT f0, f1 FROM test_table WHERE f0%2=0;
+----+-------------+------------+------------+-------+---------------+-----------+---------+------+------+----------+--------------------------+
| id | select_type | table      | partitions | type  | possible_keys | key       | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+------------+------------+-------+---------------+-----------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | test_table | NULL       | index | NULL          | idx_f0_f1 | 8       | NULL |    6 |   100.00 | Using where; Using index |
+----+-------------+------------+------------+-------+---------------+-----------+---------+------+------+----------+--------------------------+

如下sql则需要对索引字段f1通过LEFT函数取前缀后进行比较,同样只能先把索引全部取出作为初步结果集,而后再进行where子句筛选

EXPLAIN SELECT f0, f1 FROM test_table WHERE f0=3 AND LEFT(f1, 2)="33";
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+--------------------------+
| id | select_type | table      | partitions | type | possible_keys | key       | key_len | ref   | rows | filtered | Extra                    |
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+--------------------------+
|  1 | SIMPLE      | test_table | NULL       | ref  | idx_f0_f1     | idx_f0_f1 | 4       | const |    1 |   100.00 | Using where; Using index |
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+--------------------------+

转载请注明出处,原文地址: MySQL explain结果Extra中”Using Index”与”Using where; Using index”区别探究

参考

MySQL – “Using index condition” vs “Using where; Using index”
Whats the difference between “Using index” and “Using where; Using index” in the EXPLAIN
「Using where; Using index」和「Using index」 区别是什么
MySQL execution plan (Use where, Use index and Use index condition)

签名:拥抱开源,拥抱自由

原文地址:https://www.cnblogs.com/AcAc-t/archive/2022/02/28/mysql_explain_difference_between_using_index_and_using_where.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/5479.html

(0)
上一篇 2023-05-07
下一篇 2023-05-07

相关推荐

  • 什么是XPath

    什么是XPath在网页爬虫和数据抓取方面,XPath是一个非常重要的工具。XPath是一种在XML文档中进行导航和提取信息的语言。它提供了一种简洁明了的方式来定位XML文件中的节点和属性。XPath的使用广泛在数据采集、网络爬虫、数据分析等领域。

    2024-06-24
    54
  • redis数据共享_redis高级面试题

    redis数据共享_redis高级面试题我正在面试间里焦急地等待着,突然听到了门外的脚步声,随即门被打开,穿着干净满脸清秀的青年走了进来,一股男士香水的淡香扑面而来。 面试官:“平时在工作中用过Redis吗?” 我:“用的比较多。”我心中暗

    2023-05-08
    142
  • Python实现元组转列表操作

    Python实现元组转列表操作Python是一种高级编程语言,拥有简洁易懂的语法结构,但是在不同的数据结构之间的转换有时依然令初学者感到棘手。本文将阐述Python中如何将元组(tuple)转化为列表(list)。

    2024-04-22
    58
  • 使用Python计算数据的平均值

    使用Python计算数据的平均值a href=”https://beian.miit.gov.cn/”苏ICP备2023018380号-1/a Copyright www.python100.com .Some Rights Reserved.

    2024-06-05
    53
  • 提高工作效率的Python工具库

    提高工作效率的Python工具库数据处理是Python的一个强项,对于数据分析和处理,Python提供了许多好用的工具库。例如,Pandas库可以帮助我们方便地读取数据、进行数据清洗、转换和分析等。此外,Python还可以通过其他库来进行数据自动化处理,例如:

    2024-03-15
    78
  • linux hbase安装_hbase安装与配置详解

    linux hbase安装_hbase安装与配置详解环境准备 System:CentOS release 6.10 (Final) JDK:jdk1.8.0_251 注意,不同版本的安装包需要相应的jdk版本支持 step1下载安装包: # wget…

    2023-03-07
    155
  • 大数据Hadoop之——Spark on Hive 和 Hive on Spark的区别与实现「建议收藏」

    大数据Hadoop之——Spark on Hive 和 Hive on Spark的区别与实现「建议收藏」一、Spark on Hive 和 Hive on Spark的区别 1)Spark on Hive Spark on Hive 是Hive只作为存储角色,Spark负责sql解析优化,执行。这里可以

    2023-05-14
    137
  • Python实现二进制数61

    Python实现二进制数61使用二进制有什么好处呢?首先二进制是计算机可以直接处理的数字形式,这是因为在计算机内部使用的是二进制电子元器件,所以使用二进制能够更加高效地进行数值运算和存储。其次,当数据需要在不同的计算机之间传输时,使用二进制能够保证数据的准确性和一致性。

    2023-12-05
    115

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注