从具有两个单独索引的 table 中选择不是根据 where 子句中的值使用键

Selecting from a table with two separate indexes is not using a key depending on value in where clause

我正在调整我们的数据库索引并在 Mysql 5.7.32 中发现了一些奇怪的行为。这是复制问题的脚本。

我有一个 table employees,其中包含三列 idfirstnamelastname。每个 varchar 列在 table 上有两个索引。对于下面的 SELECT 语句之一,输出意外地没有使用密钥。

为什么其中一个查询没有使用索引?是因为 Miller 是 table 中的第一个值吗?或者这是 EXPLAIN 的错误?

DROP TABLE if EXISTS `employee`;
CREATE TABLE `employee` (
    `id` INT(11) NOT NULL auto_increment,
    `firstname` VARCHAR(50) NOT NULL,
    `lastname` VARCHAR(50) NOT NULL, 
    PRIMARY KEY (`id`), 
    INDEX `index_firstname` (`firstname`),
    INDEX `index_lastname` (`lastname`)
);

INSERT INTO `employee` (firstname,lastname) VALUES('alice','Miller');
INSERT INTO `employee` (firstname,lastname) VALUES('bob','Miller');
INSERT INTO `employee` (firstname,lastname) VALUES('charlie','Miller');
INSERT INTO `employee` (firstname,lastname) VALUES('doyle','Miller');
INSERT INTO `employee` (firstname,lastname) VALUES('evan','Smith');
INSERT INTO `employee` (firstname,lastname) VALUES('franz','Smith');
INSERT INTO `employee` (firstname,lastname) VALUES('gloria','Smith');
INSERT INTO `employee` (firstname,lastname) VALUES('helga','Unique');

EXPLAIN SELECT * FROM employee WHERE firstname='alice';   # uses the key 'index_firstname'
EXPLAIN SELECT * FROM employee WHERE lastname='Smith';    # uses the key 'index_lastname'
EXPLAIN SELECT * FROM employee WHERE lastname='Unique';   # uses the key 'index_lastname'

EXPLAIN SELECT * FROM employee WHERE lastname='Miller';   # does not use the key 'index_lastname'

如果索引值的采样占给定值采样的比例超过 ~25%(不准确,请参见下文),则不使用该索引。

有一个成本计算得出扫描完整 table 比使用二级索引更快(需要从主 table 获取以检索 *) .