在大型主题上收藏帖子会导致加载时间过长

这个帖子尤其让我困扰了很久。我曾问:为什么加载需要 1 到 3 分钟,甚至有时根本加载不出来?

在看到有人在 这篇 帖子中再次提到该问题后,我决定深入调查:我从那个拥有 4,500 条回复的帖子中移除了所有书签。

结果它像其他普通帖子一样瞬间加载完成。

随后我思考:还有哪些方法可以验证这一点?

  • 无论我是否将首帖或最新帖设为书签,加载时间仍然较长,虽然不是几分钟,但大约需要 10 秒。
  • 帖子数量越多,该现象越明显;我感觉在约 4000 条回复左右存在某个阈值,会导致加载时间变得如此缓慢。
  • 我在其他超过 4000 条回复的帖子中也进行了测试。
  • 一个主题拥有的书签越多,加载时间就越长。

我的推测是:在一个帖子数量很多的话题中,书签数量越多,加载所需时间就越长。


复现步骤:打开一个包含大量回复的主题,并将其中一条帖子设为书签。遗憾的是,要书签帖子需要登录,而本网站上回复最多的帖子仅有 925 条回复。

如果需要我提供更多详细信息,请随时提出。

4 个赞

我之前好像在另一个话题里向 @martin 报告过这个问题。

2 个赞

嗯,是的,你确实提到了这个:https://meta.discourse.org/t/topics-load-slow-or-not-at-all-when-they-have-many-replies-and-user-has-bookmark-in-them/166201。抱歉,我好像疏忽了这一点;我会把这个问题移到我的待办事项列表的最前面。

2 个赞

如果稳定版中存在此问题,其严重性也足以支持将其向后移植。

3 个赞

我在 Roblox 论坛上创建了一个账号,查看了 https://devforum.roblox.com/t/what-are-you-working-on-currently-2020/419774/5043,并在那里复现了该问题。没有书签时,主题加载时间约为 1.3 秒;而有书签时则需约 8 秒。我甚至遇到了 502 网关错误:

不过,我在本地创建了一个包含 5000 条帖子的主题并添加了书签,结果发现无论该主题中是否有书签,加载时间都相同::man_shrugging:。我需要继续排查……加载用户主题中标签的代码位于:

而为每条帖子查找书签的代码位于:

在我看来,这段代码并不显得异常或性能消耗大。user_post_bookmarks 只会查询一次数据库,因为它被缓存了,所以这里不存在 N+1 查询问题。此外,以下是用于检查主题级别是否存在书签的主题视图代码:

这里也没有发现任何可疑之处……

2 个赞

这会不会是我们之前在旧版本中已经修复的 bug?:thinking:

2 个赞

我不这么认为,Roblox 论坛使用的是版本 https://github.com/discourse/discourse/commit/2a268bd89b4eebe4941b98030db9d920ee98d406。自那以后,只有两个与书签相关的提交是我做的,它们都没有涉及主题书签的加载或序列化。

我想一定是有什么其他奇怪的巧合在起作用?

1 个赞

我可以在 BBS 上复现此问题。

该查询似乎存在问题,导致查询规划器出错。请查看执行计划并进行一些调整。

我猜测,只需进行一些非常微小的改动,就能将执行时间从近 4 秒降低到 1 毫秒。

提醒各位读者:启用 MiniProfiler 至关重要,它能帮助你定位有问题的查询。

5 个赞

感谢 @sam 的建议,我发现问题出在以下这行代码执行的查询计划不佳:

topic.posts.with_deleted.where(post_number: 1).first

生成的 SQL 包含 LIMIT 1,导致 index_posts_on_topic_id_and_post_number 索引未被使用,从而造成巨大延迟。我在本地无法复现此问题,因为本地数据库中几乎没有帖子;基本上,整个 Discourse 论坛中的帖子越多,此问题就越严重。我很快就会提供修复方案。

3 个赞

此问题已作为重复项关闭,参见:

@martin,问题解决后,你可以在原主题下继续发帖。

4 个赞