为什么 mysql 解释说 'using index' 而使用的索引不包含必填字段

why mysql explain says 'using index' while the index used do not contain required fields

这是 mysql(innodb) 中解释命令的输出:

explain select * from multi_index_test_tbl_1 force index(`query_index_1`) where `text_field1`='0' order by `numeric_field2` desc limit 1000000;
+----+-------------+------------------------+------+---------------+---------------+---------+-------+----------+--------------------------+
| id | select_type | table                  | type | possible_keys | key           | key_len | ref   | rows     | Extra                    |
+----+-------------+------------------------+------+---------------+---------------+---------+-------+----------+--------------------------+
|  1 | SIMPLE      | multi_index_test_tbl_1 | ref  | query_index_1 | query_index_1 | 386     | const | 53547628 | Using where; Using index |
+----+-------------+------------------------+------+---------------+---------------+---------+-------+----------+--------------------------+

tablemulti_index_test_tbl_1的架构如下:

CREATE TABLE IF NOT EXISTS `multi_index_test_tbl_1` 
(
    `text_field1` varchar(128) NOT NULL,
    `numeric_field1` float NOT NULL,
    `numeric_field2` float NOT NULL,
    `text_field2` varchar(128) NOT NULL,
    PRIMARY KEY (`text_field1`,`numeric_field1`,`text_field2`),
    KEY `query_index_1` (`text_field1`,`numeric_field2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

好像用了query_index_1。 'using index' 出现在 Extra 而索引 query_index_1 不包含 table multi_index_test_tbl_1.

中的所有字段

因为 mysql 文档说:

Using index (JSON property: 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.

我很困惑这里到底发生了什么。

啊,但确实如此 'contain required fields'。详细说明...

InnoDB 在每个 'secondary' 索引中包含 PRIMARY KEY 的所有列。所以,

KEY `query_index_1` (`text_field1`,`numeric_field2`)

真的更像

KEY `query_index_1` (`text_field1`,`numeric_field2`,
                     `numeric_field1`,`text_field2`)

在您的示例中,这包括所有列。因此,SELECT 中的所有内容,包括 * 都可以在该二级索引中找到。所以,"Using index" 是 'correct'.

这是 InnoDB 有时优于 MyISAM 的一种方式。

尝试 EXPLAIN FORMAT=JSON SELECT ... 获取更多详细信息。