典型的な正規化されたアプローチでは、非効率的なクエリが残るとは思いません。PKを持つテーブルとarticle_comments
PK(article_id, comment_id)
を持つ別のテーブルがあるとします。ページにリストされている記事ごとに、次のことを行う必要があります。comments_seen_by_user
(user_id, article_id, comment_id)
SELECT count(*) FROM article_comments ac
WHERE article_id = ? -- Parameter
AND NOT EXISTS (
SELECT 1 FROM comments_seen_by_user csbu
WHERE csbu.user_id = ? -- Parameter
AND csbu.article_id = ac.article_id
AND csbu.comment_id = ac.comment_id
)
ページに 20 個の記事を表示する場合、上記のクエリを 20 回実行し、各実行でインデックスを使用して から 10 ~ 20 行を抽出しますarticle_comments
。サブクエリ テストは、 の別のインデックス スキャンcomments_seen_by_user
なので、すべて特定のページを表示するために 20 * (20 * 2) = 800 回のインデックス付きルックアップを実行する必要があります。これは、最新の DB にとっては簡単なことです。そして、私はおそらく、PostgreSQL が見つける可能性のあるさらに優れたクエリ プランを見落としています。
これを試してみて、パフォーマンスが不足していることがわかりましたか? もしそうなら、私の最初の推測では、あなたはしばらく教育を受けていないでしょうVACUUM
. そうでなければ、1 ページあたりの記事数、または 1 記事あたりのコメント数の見積もりが間違っていたに違いありません。その場合は、詳細を更新してください。