Рассмотрим систему голосования, реализованную в PostgreSQL, где каждый пользователь может проголосовать вверх или вниз на "foo". Существует таблица foo
, в которой хранятся все "данные foo" и таблица votes
, в которой хранятся user_id
, foo_id
и vote
, где vote
равно +1 или -1.
Чтобы получить подсчет голосов для каждого foo, следующий запрос будет работать:
SELECT sum(vote) FROM votes WHERE foo.foo_id = votes.foo_id;
Но следующее будет работать так же хорошо:
(SELECT count(vote) FROM votes
WHERE foo.foo_id = votes.foo_id
AND votes.vote = 1)
- (SELECT count(vote) FROM votes
WHERE foo.foo_id = votes.foo_id
AND votes.vote = (-1))
В настоящее время у меня есть индекс на votes.foo_id
.
Каков более эффективный подход? (Другими словами, что будет работать быстрее?) Меня интересует как ответ на PostgreSQL, так и общий ответ SQL.
ИЗМЕНИТЬ
Многие ответы учитывали случай, когда vote
имеет значение NULL. Я забыл упомянуть, что в столбце голосования есть ограничение NOT NULL
.
Кроме того, многие отмечали, что первое гораздо легче читать. Да, это определенно верно, и если бы коллега написал второй, я бы взрывался с яростью, если не было необходимости в производительности. Тем не менее, вопрос по-прежнему зависит от эффективности этих двух. (Технически, если первый запрос был медленнее, не было бы таким преступлением писать второй запрос.)