3

我遇到了一个奇怪的 MySQL 索引问题。我有一张桌子views_video

CREATE TABLE `views_video` (
  `video_id` smallint(5) unsigned NOT NULL,
  `record_date` date NOT NULL,
  `region` char(2) NOT NULL DEFAULT '',
  `views` mediumint(8) unsigned NOT NULL
  PRIMARY KEY (`video_id`,`record_date`,`region`),
  KEY `video_id` (`video_id`)
)

该表包含 340 万条记录。

EXPLAIN在这个查询上运行:

SELECT video_id, views FROM views_video where video_id <= 156

我有:

+----+-------------+-------------+-------+------------------+----------+---------+------+--------+-------------+
| id | select_type | table       | type  | possible_keys    | key      | key_len | ref  | rows   | Extra       |
+----+-------------+-------------+-------+------------------+----------+---------+------+--------+-------------+
|  1 | SIMPLE      | views_video | range | PRIMARY,video_id | video_id | 2       | NULL | 587984 | Using where |
+----+-------------+-------------+-------+------------------+----------+---------+------+--------+-------------+

但是当我EXPLAIN在这个查询上运行时:

SELECT video_id, views FROM views_video where video_id <= 157

我有:

+----+-------------+-------------+------+------------------+------+---------+------+---------+-------------+
| id | select_type | table       | type | possible_keys    | key  | key_len | ref  | rows    | Extra       |
+----+-------------+-------------+------+------------------+------+---------+------+---------+-------------+
|  1 | SIMPLE      | views_video | ALL  | PRIMARY,video_id | NULL | NULL    | NULL | 3412892 | Using where |
+----+-------------+-------------+------+------------------+------+---------+------+---------+-------------+

video_id是从1到1034。156到157之间没有什么特别的。

这里会发生什么?

* 更新 *

我在数据库中添加了更多数据。现在video_id是从 1 到 1064。表现在有 380 万条记录。差变成 114 和 115。

4

3 回答 3

2

如果您在创建表后添加/删除了大量数据,那么值得尝试对其进行 ANALYZE TABLE。它经常解决很多幻像索引问题,即使在大表上也非常快。

更新:此外,与表中的行数相比,唯一索引值非常低。当单个索引值指向太多行时,MySQL 不会使用索引。尝试使用属于主键的另一列进一步限制查询。

于 2012-07-12T21:15:32.583 回答
2

可能是关键人群

运行这些

SELECT (COUNT(1)/20) INTO @FivePctOfData FROM views_video;
SELECT COUNT(1) videpidcount,video_id FROM FROM views_video
WHERE id <= 157 GROUP BY video_id;

当其中一个键达到 5% 阈值时,查询优化器可能会休假。

你说有 340 万行。5% 将是 170,000。也许在查询优化器生命周期中的某个时间点超过了这个数字。

于 2012-07-12T21:27:54.060 回答
2

我猜有 340 万条记录,而您的密钥只有 1064 个可能的条目,您的选择性非常低。(换句话说,有很多重复项,这使得它作为键的用处要小得多。)优化器正在做出最好的猜测,是否使用该键更有效。您已经找到了该决定的门槛。

于 2012-07-12T21:42:38.287 回答