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

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的官方文档说明可以得出以下三点:

Using where仅表示是否存在where子句限制对结果集进行筛选后返回

Using Index仅表示是否使用了覆盖索引,即查询涉及字段均可以从一个索引中获得,单独的Using Index表示从索引中获取返回结果集即可直接作为最终结果返回。

出现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.heiqu.com/zzwfjx.html