Я не верю, что типичный нормализованный подход оставит вас с неэффективными запросами. Предположим, у вас есть стол article_comments
с PK (article_id, comment_id)
и еще один стол comments_seen_by_user
с PK (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 проиндексированных поисков, которые нужно выполнить, чтобы показать данную страницу. Это не пот, для современной БД. И я, вероятно, упускаю из виду даже лучшие планы запросов, которые может найти PostgreSQL.
Вы пробовали это и находили желаемое исполнение? Если это так, то я думаю, что вы давно не работали. В противном случае у меня должны быть неверные оценки количества статей на странице или комментариев на статью - обновите данные в этом случае.