在我们的 MySQL 5.5 数据库中,我们有以下具有 30M+ 行的 InnoDB 表:
+----------------+-------------+-----------------+--------+
| participant_id | question_id | given_answer_id | status |
+----------------+-------------+-----------------+--------+
| 500 | 12 | 25 | 0 |
+----------------+-------------+-----------------+--------+
participant_id + question_id + given_answer_id 的组合是唯一的。
目前我们有以下键:
主键(按此顺序)
- 参与者编号
- question_id
- given_answer_id
索引键
- question_id
对于这个表,我们的应用程序中有两种选择查询:
[...] WHERE participant_id = x AND question_id = y AND given_answer_id = z;
和
[...] WHERE question_id = x;
通常,每个 participant_id 都有 0 到 <100 行具有不同的 question_id。反过来,每个 question_id 可以有无限(通常不超过 100 000)行和不同的 participant_ids。第一个查询比第二个查询执行得更频繁。
当我们执行以下查询时,它会向我们显示查找到的32096 行:
EXPLAIN SELECT * FROM example WHERE question_id = 500;
+----+-------------+-----------+------+---------------+-------------+---------+-------+-------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+-------------+---------+-------+-------+-------+
| 1 | SIMPLE | example | ref | question_id | question_id | 8 | const | 32096 | |
+----+-------------+-----------+------+---------------+-------------+---------+-------+-------+-------+
然而,当我们执行相同的查询时,没有 EXPLAIN 仅返回 18732 行。
我们需要在此表上使用哪些索引来防止这种开销,但仍能对两种查询执行?
下面是创建这个表的代码:
CREATE TABLE `example` ( `participant_id` BIGINT(20) UNSIGNED NOT NULL, `question_id` BIGINT(20) UNSIGNED NOT NULL, `given_answer_id` BIGINT(20) UNSIGNED NOT NULL, `status` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY (`participant_id`, `question_id`, `given_answer_id`), INDEX `question_id` (`question_id`) ) ENGINE=InnoDB;
最佳答案
我已按照推荐将此问题发布到 dba.stackexchange.com,并收到了全面的答复:https://dba.stackexchange.com/questions/49275/mysql-looking-up-more-rows-than-needed-indexing-issue
关于MySQL 查找比需要更多的行(索引问题),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18617893/