【发布时间】:2013-02-06 12:55:55
【问题描述】:
考虑一个在 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 为空的情况。我忘了提到在投票列上有一个NOT NULL 约束。
此外,许多人一直指出第一个更容易阅读。是的,这绝对是真的,如果一位同事写了第二个,除非有表演的必要性,否则我会愤怒地爆炸。无论如何,问题仍然在于两人的表现。 (从技术上讲,如果第一个查询方式慢,那么编写第二个查询就不是犯罪了。)
【问题讨论】:
-
EXPLAIN ANALYZE ...?! -
我想不出第二个可以更快的任何方式 - 您仍然需要阅读每一行的
vote列。 -
@deceze 是对的。但是,我建议查看一个重要方面:使用 sum() 的第一个方面是可读的,并且一眼就能理解。第二个立即在我的大脑中抛出一个“WTFException”,然后在能够破译它之后,whoDidThis() 立即被一个不可屏蔽的中断运行。这种方法的副作用可能包括用大鳟鱼打某人...
-
您想同时获得一个特定
foo的分数,还是所有foo的分数? -
你在实现 StackOverflow!?
标签: sql postgresql aggregate-functions