数据库查询的最佳方法是什么,返回的结果类似于您关注的Twitter推文的推文?

时间:2012-03-10 17:45:14

标签: mysql database query-optimization database-performance

我的网站允许用户提交帖子并订阅其他人的帖子。该网站的主页显示用户关注的人员的最新帖子。用户可以关注的人数没有限制。一些用户正在关注数千名其他用户。一些用户发布了超过15,000个帖子。

posts数据库表是这样组织的(为清楚起见,省略了一些不相关的列):

id
author_id
post_content
date_added

我有2个工作解决方案,但我不确定这两种方法是否是最好的方法:

解决方案1:

  1. 获取用户关注的author_ids列表。
  2. 在表格中查询与任何author_id匹配的帖子:

     SELECT id FROM posts
     WHERE author_id IN (12, 34, 56, 78, 90, ...)
     ORDER BY date_time DESC
     LIMIT 100;
    
  3. 将结果缓存N分钟。
  4. 这样可行,但在用户关注数千人时会抓取。

    解决方案2:

    1. 获取用户关注的author_ids列表。
    2. 对于每个作者ID,只需获取其帖子ID的缓存Feed即可。 (此Feed用于作者页面)
    3. 将所有这些作者的所有帖子ID合并到一个巨大的数组中,并按降序对它们进行排序(这恰好有效,因为每个帖子都会获得一个自动递增的ID)。
    4. 缓存并返回最近的100个帖子ID;
    5. 这样可行,但有时会在返回数千个用户订阅源并将其合并到包含100,000多个项目的数组时进行爬网。当我关心的是最近的100件物品时,感觉有点矫枉过正。此外,并非所有用户订阅源都在缓存中。一些旧用户可能不再使用该网站,但仍然会有新用户跟随,导致旧用户的Feed被新查询(然后进行缓存)。

      这些是最佳解决方案吗?如果没有,那是什么?

2 个答案:

答案 0 :(得分:0)

怎么样(未经测试,但你明白了):

SELECT id FROM posts
CROSS JOIN followers ON posts.author_id = followers.user_id
WHERE followers.followed_by_user_id = INSERT_USER_ID_HERE
ORDER BY posts.date_time DESC
LIMIT 100;

SELECT id FROM posts
WHERE author_id IN (
  SELECT user_id FROM followers 
  WHERE followed_by_user_id = INSERT_USER_ID_HERE
)
ORDER BY date_time DESC
LIMIT 100;

注意:为了澄清,表followers包含两列user_idfollowed_by_user_id。如果某行包含值(user_id:7followed_by_user_id:42),则表示用户42跟随用户7。

答案 1 :(得分:0)

优化解决方案2 ,避免合并和排序所有帖子ID:

  1. 创建一个数组来保存结果并复制第一作者的前100个帖子ID的内容,并按id排序。
  2. 每位作者:
    1. 检查结果数组中的最小id是否大于作者帖子的最大id
    2. 如果是,则跳过该作者,因为他的所有帖子都比结果数组中的帖子旧。
    3. 如果不是,则将作者的前100个帖子与结果数组合并,排序,然后仅保留前100个帖子。
  3. 此外,您可以维护一个具有每个作者的最大帖子ID的数组。在获取作者的前100个帖子之前,您可以检查此数组。这将避免获取/缓存非活动用户的帖子。


    对于解决方案1 ​​,按id排序比date_time排序要快一些。