"Using index"和"Using where; Using index"在EXPLAIN中的区别是什么?

38

在mysql的explain中的额外字段中,你可以得到:

  • Using index
  • Using where; Using index

这两者之间有什么区别?

为了更好地解释我的问题,我将使用以下表格:

CREATE TABLE `test` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `another_field` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

INSERT INTO test() VALUES(),(),(),(),();

最终结果会变成这样的内容:

SELECT * FROM `test`;

id  another_field
1   0
2   0
3   0
4   0
5   0

在我的研究中,我发现:

为什么这个查询使用了 where 而不是 index?

EXPLAIN 的输出有时会误导。

例如,filesort 与文件无关,using where 并不意味着使用了 WHERE 子句,而 using index 可能 出现在表上,即使没有定义单个索引。

Using where 只是表示在表上有某些限制性子句(WHEREON),并且不会返回所有记录。请注意, LIMIT 不计算为限制性子句(但它可以)。

Using index 表示从索引中返回了所有信息,而不需要在表中查找记录。这仅在查询所需的所有字段都被索引覆盖时才可能实现。

由于您选择了 *,这是不可能的。除了 category_idboard_iddisplayorder 之外的字段未被索引覆盖,必须进行查找。

并且我还发现:

https://dev.mysql.com/doc/refman/5.1/en/explain-output.html#explain-extra-information

Using index

仅使用索引树中的信息从表中检索列信息,而不必进行额外的搜索才能读取实际行。当查询仅使用单个索引的列时,可以使用这种策略。

如果“Extra”列还说“Using where”,则表示正在使用索引来执行关键值的查找。如果没有使用 where,则优化器可能会读取索引以避免读取数据行, 但不使用它进行查找。例如,如果该索引是查询的覆盖索引,则优化器可能会在不使用它进行查找的情况下扫描它。

对于具有用户定义的聚集索引的 InnoDB 表,即使 Extra 列中缺少 Using index,也可以使用该索引。如果类型为 index 并且键为 PRIMARY,则是这种情况。

(看第二段)

我对此的问题:

首先,我没有按照原文的方式理解第二段。

其次:

以下查询返回

EXPLAIN SELECT id FROM test WHERE id = 5;

id  select_type table   type    possible_keys   key     key_len ref     rows    Extra
1   SIMPLE      test    const   PRIMARY         PRIMARY 8       const   1       Using index

(向右滚动)

另一个查询返回:

EXPLAIN SELECT id FROM test WHERE id > 5;

id  select_type table   type    possible_keys   key     key_len ref     rows    Extra
1   SIMPLE      test    range   PRIMARY         PRIMARY 8       NULL    1       Using where; Using index

(向右滚动)

除了一个查询使用范围搜索而另一个使用常量搜索之外,两个查询都在表上使用了某些限制性子句(WHERE或ON),并且不会返回所有记录。

第二个查询中的 Using where; 是什么意思?而第一个查询没有这个是什么意思?


额外内容:

Using index condition; Using where 有什么区别? (我没有在一个小型自包含代码片段中重现它的示例)


回答额外问题。(我之前没找到它,因为我看的是旧版本的mysql文档<打了自己一巴掌>。) - J-Rou
1个回答

32
当你在explain的Extra部分看到Using Index时,这意味着(覆盖)索引已经足够满足查询需求。
在你的例子中:SELECT id FROM test WHERE id = 5;,由于可以只使用索引来满足查询(仅访问id),所以服务器不需要访问实际表格。(正如explain所述)。如果您还不知道,PK是通过唯一索引实现的。
当你看到Using Index; Using where时,这意味着首先使用索引检索记录(不需要实际访问表格),然后在结果集上执行where条件的过滤。
在这个例子中:SELECT id FROM test WHERE id > 5;,仍然从索引中获取id,然后应用大于条件来过滤不符合条件的记录。

1
只是确认一下:SELECT id FROM test WHERE id > 5; 不会从磁盘读取行,对吗?此外,在这两种情况下,MySQL 都涵盖了索引的相同部分,并在 B 树中到达了相同的值。是否存在任何重要的计算差异? - J-Rou
另外补充一点,仅为了完善您的回答。关键字的唯一状态不会产生影响。alter table test add key another_fileld(another_field); explain select another_field from test where another_field = 0 只返回 Using index - J-Rou
@J-Rou:不,它没有访问硬盘。什么是计算差异? - Cratylus
唯一键的状态不会受到影响。不会,我只是向您提及了PK的实现方式。 - Cratylus
5
如果出现 "Using where; Using Index",意思是查询语句正在使用where子句和索引来加速查找。 - haneulkim
1
我也有这个问题,就像 Using where; Using Index ?,在我的情况下会涉及到 100k 行,而不是使用索引。为什么会这样,我该如何改变它? - webdevbyjoss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接