首页 > 解决方案 > 我怎样才能更快地进行此查询?(postgreSQL)

问题描述

目标 - 第 1 天滚动留存率(百分比)

问题:

1)我怎样才能加快这个查询?

2)这个对数字的对话是减慢查询?

3)我还有其他选项可以以其他方式舍入()吗?还是最佳?

询问:

SELECT date(reg_time), round(CAST(count(DISTINCT du.uid) / count(DISTINCT users.uid)::float * 100 AS numeric), 2) AS rolling_retention_day1
FROM users 
LEFT JOIN dailyusers du 
ON users.uid = du.uid
AND date(reg_time) BETWEEN current_date - interval '30' DAY AND current_date 
AND date(reg_time) + 1 <= day
GROUP BY date(reg_time); 

标签: sqlpostgresql

解决方案


使用正确的索引,我怀疑这会更快:

SELECT reg_date, AVG(du_flag) as rolling_retention_day1
FROM (SELECT date(u.reg_time) as reg_date,
             (CASE WHEN EXISTS (SELECT 1 
                                FROM dailyusers du
                                WHERE du.uid = u.uid AND
                                      date(u.reg_time) + 1 <= du.day
                               )
                   THEN 1 ELSE 0
              END) as du_flag
      FROM users u
      WHERE u.reg_time >= current_date - interval '30' day AND
            u.reg_time < current_date + interval '1' day
     )
GROUP BY reg_date;

你想要索引users(reg_time)dailyusers(uid, day)。这假设uid是唯一的users,这对我来说很有意义。

如果您真的关心平均值的格式,那么您可以这样做:

AVG(du_flag)::decimal(4, 2)

这是我对您给出的查询所能做的最好的事情。可能有更好的方法来编写查询。如果您需要帮助,我建议您使用示例数据、所需结果以及查询正在做什么(或应该做什么)的解释提出另一个问题。


推荐阅读