4M 行表上的简单查询很慢

Que*_*tin 3 mysql performance optimization query-performance

我在生产中有一个pageviews包含 4M 行的 MySQL 表,用于记录用户在帖子上的页面浏览量。我需要知道特定用户阅读了哪些帖子,但此请求最多需要 15 秒才能执行:

SELECT post_id
FROM pageviews
WHERE user_id = 981
GROUP BY post_id
Run Code Online (Sandbox Code Playgroud)

下面是执行计划:

mysql> EXPLAIN SELECT post_id FROM visits WHERE user_id = 981 GROUP BY post_id;
+----+-------------+--------+------+---------------+---------+---------+-------+-------+----------------------------------------------+
| id | select_type | table  | type | possible_keys | key     | key_len | ref   | rows  | Extra                                        |
+----+-------------+--------+------+---------------+---------+---------+-------+-------+----------------------------------------------+
|  1 | SIMPLE      | visits | ref  | user_id       | user_id | 5       | const | 54696 | Using where; Using temporary; Using filesort |
+----+-------------+--------+------+---------------+---------+---------+-------+-------+----------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

我不知道如何寻找缓慢的原因:也许表没有很好地配置,mysql 服务器没有很好地调整,其他查询锁定的东西,......或者也许只有 4M 行是开始分区的合适大小.

生产数据库位于 Amazon RDS 上

创建表`页面浏览量`(
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) 默认为空,
  `post_id` int(11) 默认为空,
  `created_at` 日期时间非空,
  主键(`id`),
  KEY`post_id`(`post_id`),
  KEY`user_id`(`user_id`),
  KEY`created_at`(`created_at`),
  约束`FK_444839EAA76ED395`外键(`user_id`)引用`users`(`id`),
  约束`visits_ibfk_2`外键(`post_id`)引用`posts`(`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4587432 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

jyn*_*nus 7

除了@ tombom的建议,在创建索引(user_id, post_id)的替代(或补充,但较少的指标越好)上USER_ID和POST_ID单独的索引将简化查询,可能摆脱文件排序和临时表,加给你覆盖索引的好处。

如果您有足够大的缓冲池并且查询相对频繁,这可能会显着降低查询执行速度。

如果这样做之后,查询仍然很慢,您将需要进行(预)缓存以加快查询执行速度。