【发布时间】:2021-04-23 10:07:58
【问题描述】:
我有 2 个视图:
预后评分:
| user_id | isGoodPrognosis | pts_won | good_gap | good_score |
|---|---|---|---|---|
| 1 | true | 1 | 0 | 0 |
| 1 | true | 1 | 0 | 0 |
| 2 | true | 3 | 1 | 1 |
| 2 | false | 0 | 0 | 0 |
question_scores:
| user_id | isGoodPrognosis | pts_won |
|---|---|---|
| 1 | false | 0 |
| 2 | true | 10 |
并且想创建第三个视图来计算用户的总分: (我还需要 users 表中的其他数据)
score_calculations:
| user_id | pts__won | good_gap | good_score | good_winner | company_id | team_id | name |
|---|---|---|---|---|---|---|---|
| 1 | 2 | 0 | 0 | 2 | 1 | 1 | John |
| 2 | 13 | 1 | 1 | 1 | 1 | 1 | Sam |
为此,我这样做了:
CREATE VIEW score_calculations
AS SELECT
users.id as user_id,
users.name as name,
users.company_id as company_id,
users.team_id as team_id,
users.email_verified AS email_verified,
users.banned AS banned,
-- users.email as email,
SUM(COALESCE(prognosis_scores."pts_won", 0) + COALESCE (question_scores."pts_won", 0) ) as pts_won,
SUM(prognosis_scores."good_gap") as good_gap,
SUM(prognosis_scores."good_score") as good_score,
SUM(prognosis_scores."isGoodPrognosis"::INT) as good_winner
FROM users
LEFT JOIN prognosis_scores
ON prognosis_scores.user_id=users.id
LEFT JOIN question_scores
ON question_scores.user_id=users.id
GROUP BY users.id , users.name, users.company_id,team_id,email_verified,banned;
但SUM(COALESCE(prognosis_scores."pts_won", 0) + COALESCE (question_scores."pts_won", 0) ) as pts_won, 效果不佳:SUM with multiple LEFT JOINS with VIEWS
所以我最终得到了这个:
CREATE VIEW score_calculations
AS SELECT u.id as user_id, u.name, u.company_id, u.team_id, u.email_verified,u.banned,
-- users.email as email,
COALESCE(ps.pts_won, 0) + COALESCE (qs.pts_won, 0) as pts_won,
ps.good_gap, ps.good_score, ps.good_winner
FROM users u LEFT JOIN LATERAL
(SELECT SUM(ps."pts_won") as pts_won,
SUM(ps.good_gap) as good_gap,
SUM(ps.good_score) as good_score,
SUM(ps."isGoodPrognosis"::INT) as good_winner
FROM prognosis_scores ps
WHERE ps.user_id = u.id
) ps
ON 1=1 LEFT JOIN LATERAL
(SELECT SUM(qs."pts_won") as pts_won
FROM question_scores qs
WHERE qs.user_id = u.id
) qs
ON 1=1;
问题是第二块代码很慢,当我尝试运行SELECT * FROM score_calculations时,执行时间大约是16s,而第一块代码很快,执行时间大约是400ms。
对于这个测试,我有大约 1000 个用户和大约 30000 个预测分数
问题是:如何优化或更改第二段代码(score_calculations 视图)?
【问题讨论】:
-
要诊断性能问题,请使用 EXPLAIN ANALYZE。将分析查询的结果包含在您的问题中以获得最佳答案。
标签: sql database postgresql view