是否可以提高此子查询的性能?
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;
对于我的申请,我有一个主题 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;