查询的提升效果

问题描述 投票:1回答:1

我正在构建一个论坛应用程序,用户可以在其中发布消息。这些消息可以被其他人看到。

表结构(简化):

// table: users
user_id | username | gender
---------------------------
1       | john     | m
2       | jane     | f
...

// table: posts
post_id | user_id | title
-------------------------
1       | 1       | Hello
...

// table: views
view_id | post_id | user_id | timestamp
---------------------------------------
1       | 1       | 2       | 2020-01-01 12:00:00
...

现在,我想创建一个查询以返回有关此帖子的一些统计信息。我想获得唯一的视图(每次用户查看一个帖子时,都会记录该日志,但是我只想对所有用户计数一次),并且想要获得男女比例。

SELECT
    title,
    (SELECT COUNT(DISTINCT user_id) FROM views WHERE post_id = 1) AS unique_views,
    (SELECT COUNT(user_id) FROM users WHERE gender = 'm' AND user_id IN (SELECT user_id FROM views WHERE post_id = 1) AS male_views,
    (SELECT COUNT(user_id) FROM users WHERE gender = 'f' AND user_id IN (SELECT user_id FROM views WHERE post_id = 1) AS female_views
FROM
    posts
WHERE
    post_id = 1

该查询有效,但这是一个包含5个子查询的查询。我尚无大量数据需要测试,但是当我说+ 1m用户,+ 1m帖子和+ 10m视图时,恐怕性能会下降。

一种不同的方法是将查询完全拆分为多个查询:一个用于全部唯一视图,另一种用于性别视图(具有唯一性),但是仍然总共是6个查询。

我正在使用PostgreSQL,并且在users.user_idusers.genderposts.post_idviews.view_idviews.post_id上有一个索引。

Question:还有另一种方法(例如,使用JOIN)来执行此查询,并且当数据库容量增加时会具有更好的性能吗?

sql postgresql group-by query-performance
1个回答
0
投票

您可以加入并执行条件聚合,而不是嵌套子查询:

select 
    p.title,
    count(distinct u.user_id) unique_views,
    count(u.user_id) filter(where u.gender = 'm') male_views,
    count(u.user_id) filter(where u.gender = 'f') female_views
from views v
inner join users u on u.user_id = v.user_id
inner join posts p on p.post_id = v.post_id
where p.post_id = 1
group by p.post_id, p.title
© www.soinside.com 2019 - 2024. All rights reserved.