大規模トピックの投稿をブックマークすると、読み込み時間が異常に長くなる

このスレッドは特に、長い間私を悩ませていました。なぜ読み込みに1〜3分もかかるのか、あるいはそもそも読み込まないのかと疑問に思いました。

この投稿で同じ問題が共有されているのを見て、調査することにしました。投稿数が4,500あるスレッドからすべてのブックマークを削除しました。

すると、他の投稿と同様に瞬時に読み込まれました。

そこで、他にどのような方法でこれを検証できるかと考えました。

  • 最初の投稿か最新の投稿かをブックマークしたかどうかに関わらず、読み込みに時間がかかりました。ただし、数分ではなく約10秒程度でした。
  • 投稿数が多いスレッドではこの影響がさらに顕著でした。おそらく4,000件前後の投稿数が閾値となり、読み込み時間がこれほど遅くなるのだと思います。
  • 4,000件を超える投稿がある他のスレッドでも同様のテストを行いました。
  • トピックのブックマーク数が多いほど、読み込みに時間がかかります。

私の仮説としては、投稿数の多いトピックにブックマークが多いほど、読み込みに時間がかかるということです。


再現手順:投稿数が非常に多いトピックを開き、1つブックマークします。参照されているスレッドではブックマークするにはログインが必要で、このウェブサイトで返信数が最も多いスレッドは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 フォーラムにアカウントを作成し、What are you working on currently? (2020) - #5043 by FLYSLENDY04 - Creations Feedback - Developer Forum | Roblox を確認したところ、そこで問題が再現しました。ブックマークなしではトピックの読み込みに約 1.3 秒かかるのに対し、ブックマークありでは約 8 秒かかります。502 Bad Gateway エラーに遭遇したこともあります:

しかし、ローカルで 5000 件の投稿があるトピックを作成し、ブックマークを設定しても、トピック内にブックマークがあってもなくても読み込み時間は同じでした :man_shrugging:。引き続き調査する必要があります… ユーザーのトピック内でのブックマークを読み込むコードはここにあります:

また、各投稿のブックマークを検索するコードはここにあります:

これらは異常に見え、パフォーマンスに負荷をかけるものとは思えません。user_post_bookmarks はメモ化されているため、データベースへのクエリは 1 回だけ実行され、N+1 問題は発生しません。また、トピックレベルでブックマークがあるか確認するためのトピックビューのコードも以下に示します:

ここにも不審な点は見当たりません…

「いいね!」 2

もしかして、以前のバージョンですでに修正済みのバグでしょうか?:thinking:

「いいね!」 2

そうは思いません。Roblox フォーラムは Version bump to v2.6.0.beta3 · discourse/discourse@2a268bd · GitHub のバージョンにあります。それ以降、私が行ったブックマーク関連のコミットは 2 つだけですが、どちらもトピックのブックマークの読み込みやシリアライズとは無関係です。

何か他の奇妙な偶然が起きているのでしょうか?

「いいね!」 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