索引是否需要覆盖所有选定的列?

n00*_*00b 1 mysql index

我正在使用带有非常基本查询的 AWS Aurora 数据库(MySQL 引擎):

SELECT * FROM phones_table where phone_number = 98371381;
Run Code Online (Sandbox Code Playgroud)

phone_number列上的该表有一个索引:

mysql> show index from vaya_call_data_record;
+--------------+------------+--------------------------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table        | Non_unique | Key_name                       | Seq_in_index | Column_name    | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------+------------+--------------------------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| phones_table |          0 | PRIMARY                        |            1 | id             | A         |     4415670 |     NULL | NULL   |      | BTREE      |         |               |
| phones_table |          1 | idx_phones_table_phone_number  |            1 | phone_number   | A         |      183986 |     NULL | NULL   | YES  | BTREE      |         |               |
+--------------+------------+--------------------------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
Run Code Online (Sandbox Code Playgroud)

当我运行解释计划时,查询不使用该索引。

mysql> explain SELECT * FROM phones_table where phone_number = 98371381;
+----+-------------+-----------------------+------+----------------+------+---------+------+---------+-------------+
| id | select_type | table                 | type | possible_keys  | key  | key_len | ref  | rows    | Extra       |
+----+-------------+-----------------------+------+----------------+------+---------+------+---------+-------------+
|  1 | SIMPLE      | phones_table          | ALL  |  NULL          | NULL | NULL    | NULL | 4415670 | Using where |
+----+-------------+-----------------------+------+----------------+------+---------+------+---------+-------------+
Run Code Online (Sandbox Code Playgroud)

如果我将查询更改为仅使用phone_number列,则使用索引。

mysql> explain SELECT phone_number FROM phones_table where phone_number = 98371381;
+----+-------------+-----------------------+------+----------------+-------------------------------+---------+------+---------+-------------+
| id | select_type | table                 | type | possible_keys  | key                           | key_len | ref  | rows    | Extra       |
+----+-------------+-----------------------+------+----------------+-------------------------------+---------+------+---------+-------------+
|  1 | SIMPLE      | phones_table          | ALL  |  NULL          | idx_phones_table_phone_number | NULL    | NULL | 4415670 | Using where |
+----+-------------+-----------------------+------+----------------+-------------------------------+---------+------+---------+-------------+
Run Code Online (Sandbox Code Playgroud)

这似乎表明我需要索引中选择的所有列,这不是我对索引如何工作的理解。这是 MySQL 还是 Aurora 特定行为?

Ric*_*mes 6

简短的回答:没有。

长答案:

  • “覆盖”索引通常比非覆盖索引好。

  • 您提到的查询的覆盖索引将包含表中的所有列。如果有超过 5 列,这通常是一个“坏”主意。

但是……我怀疑这不是真正的问题,也不是真正的问题。

是什么DATATYPEphonenumber?我怀疑是VARCHAR(...),对吗?然而,您通过说 来要求进行数字比较where phone_number = 98371381

添加引号(并确保它被索引) where phone_number = "98371381"。根据表名,我怀疑那是PRIMARY KEY? 如果是这样,PRIMARY KEY(phone_number)那就比任何“覆盖”索引都好。

SHOW CREATE TABLE在询问性能问题时始终提供。否则,我们必须猜测太多东西(数据类型、PK、列数、引擎等)。