是否可以提高此子查询的性能?

Is it possible to improve the performance of this subquery?

对于我的申请,我有一个主题 table 和一个投票 table。投票选项为 -1、0 和 1。我正在尝试查找每个主题被投票为 -1 和 1 的次数。

所以要搞清楚,我在做很多子查询,每个子查询都用find total number of -1 or 1 votes and then divide by the total number of votes的算法。

不幸的是,我想出的东西很慢。部分原因是我计算了两次计数,但我不确定是否可以从外部查询中引用它。

这个性能可以提高吗?

SELECT title,
  (SELECT COUNT(vote)::float8 FROM vote WHERE topic_id = v1.topic_id AND vote_choice = -1) 
/ (SELECT COUNT(vote)::float8 FROM vote WHERE topic_id = v1.topic_id) as lp,
  (SELECT COUNT(vote)::float8 FROM vote WHERE topic_id = v1.topic_id AND vote_choice = 1) 
/ (SELECT COUNT(vote)::float8 FROM vote WHERE topic_id = v1.topic_id) as rp
FROM topic
JOIN vote v1 ON topic.id = v1.topic_id 
GROUP BY v1.topic_id, topic.title;

我会使用 FILTER 而不是相关子查询:

SELECT 
    title,
    1.0 * COUNT(*) FILTER(WHERE vote_choice = -1) / COUNT(*) as lp,
    1.0 * COUNT(*) FILTER(WHERE vote_choice = 1)  / COUNT(*) as rp
FROM topic
JOIN vote v1 ON topic.id = v1.topic_id 
GROUP BY v1.topic_id, topic.title;

根据您的描述,这可以使用条件聚合来完成:

select title, 
       count(vote) as total_count,
       count(vote)::numeric filter (where vote_choice = -1) / count(vote)::numeric as lp,
       count(vote)::numeric filter (where vote_choice = 1) / count(vote) as rp
from topic t
  join vote v on t.id = v.topic_id
group by title;