Поскольку вы спрашиваете о передовых методах ... "положительные и отрицательные голоса", появляющиеся в вашей таблице сообщений, выглядят так, как будто вы дублируете данные в своей базе данных.Это проблема, потому что теперь вам всегда нужно беспокоиться о том, являются ли данные синхронизированными и правильными.Если вы хотите узнать количество поднятых голосов, подсчитайте их, не сохраняйте их в таблице Post.Я не уверен, что это то, что вы делаете, но это предположение.
На ваш запрос ... Вы, вероятно, получите лучшую производительность, используя подзапрос JOINed вместо того, как он у вас есть.Со скалярными подзапросами в качестве столбцов их нужно запускать один раз для каждой возвращаемой строки.Это может быть довольно большой удар по производительности, если вы возвращаете кучу строк.Вместо этого попробуйте:
SELECT
P.id,
P.name,
P.body,
P.upvotes,
P.downvotes,
COALESCE(UV.cnt, 0) AS upvotes2,
COALESCE(DV.cnt, 0) AS downvotes2
FROM
dbo.Posts P
LEFT OUTER JOIN (SELECT post_id, COUNT(*) cnt FROM dbo.UpVotes GROUP BY post_id) AS UV ON UV.post_id = P.id
LEFT OUTER JOIN (SELECT post_id, COUNT(*) cnt FROM dbo.DownVotes GROUP BY post_id) AS DV ON DV.post_id = P.id
Сравните его с вашим собственным запросом и посмотрите, дает ли он более высокую производительность.
РЕДАКТИРОВАТЬ: Несколько других авторов рекомендовали использовать одну таблицу для увеличения / уменьшения.голосов.Они абсолютно правильны.Это делает запрос еще проще и, вероятно, намного быстрее:
SELECT
P.id,
P.name,
P.body,
P.upvotes,
P.downvotes,
SUM(CASE WHEN V.vote_type = 'UP' THEN 1 ELSE 0 END) AS upvotes2,
SUM(CASE WHEN V.vote_type = 'DOWN' THEN 1 ELSE 0 END) AS downvotes2,
FROM
dbo.Posts P
LEFT OUTER JOIN Votes V ON
V.post_id = P.id
GROUP BY
P.id,
P.name,
P.body,
P.upvotes,
P.downvotes