【问题标题】:Caching aggregrates that are needed for sorting in MySQL?缓存 MySQL 中排序所需的聚合?
【发布时间】:2021-11-13 07:28:45
【问题描述】:

例如,考虑一个具有 2 个 MySQL 表的应用程序:posts 和 cmets。我想获取按最新评论时间排序的帖子。如果每个帖子有很多 cmets,这会很慢。我想在某处缓存每个帖子的最新评论时间。

如果我在 Redis 中缓存每个帖子的最新评论时间,那么我不能使用它在 MySQL 中进行排序。以下是我能想到的方法:

  1. 在帖子表中添加“最新评论时间”列,然后在创建新评论时更新此列(可能会出现性能问题,因为 MySQL 会锁定该行)

  2. 创建仅包含帖子 ID 和最新评论时间的新表,然后在创建新评论时更新此表(需要加入主帖子表)

  3. 将元组(最新评论时间,帖子ID)存储在Redis Sorted Sets中,然后从Redis中获取帖子ID(如果我在where子句中有很多条件,那么很难表示这些条件在 Redis 中)

我主要关心的是更新最新评论时间的频率。即使我对它进行批处理(例如每分钟最多更新一次每个帖子),它仍然可能很慢。

这些方法中哪些是“好”或“坏”?有更好的方法吗?

【问题讨论】:

  • 您需要执行的实际查询是什么?您是否考虑过为您的表编制索引?
  • 查询是否仅限于单个userComments 表中有 user_id 吗?请为相关表格提供SHOW CREATE TABLE

标签: mysql caching redis


【解决方案1】:

一位用户对每个帖子的最新评论:

SELECT p.*
    FROM ( SELECT post_id, MAX(dt) AS last_comment_dt
               FROM Comments
               WHERE user_id = ? 
               GROUP BY post_id ) AS x
    JOIN Posts AS p  USING(post_id)
    ORDER BY last_comment_dt DESC

索引:

Comments:  INDEX(user_id, post_id, dt)

每个帖子的最新评论:

SELECT p.*
    FROM ( SELECT post_id, MAX(dt) AS last_comment_dt
               FROM Comments
               GROUP BY post_id ) AS x
    JOIN Posts AS p  USING(post_id)
    ORDER BY last_comment_dt DESC

索引:

Comments:  INDEX(post_id, dt)

【讨论】:

  • 假设我们正在浏览所有帖子,这将遍历每个帖子的每条评论
  • 我真的需要看到CREATE TABLEs,这样我才能了解用户、帖子和 cmets 之间的关系。在某些架构设计中,“评论”是“帖子”的特例。
猜你喜欢
  • 2021-02-11
  • 2021-02-11
  • 2015-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多