我怎样才能更快地查询? (postgreSQL)

时间:2018-12-16 16:37:41

标签: sql postgresql

目标-第1天的滚动保留百分比

问题:

1)我如何加快此查询的速度?

2)这种与数字的对话会减慢查询速度?

3)我是否还有其他选择可以将round()换成其他方式?还是最佳?

查询:

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); 

2 个答案:

答案 0 :(得分:0)

reg_time包含在日期功能中。

如果reg_time是索引列,则用日期功能将reg_time括起来会中断索引搜索。您需要考虑不要使用date(reg_time)

您还可以使用SQL Explain Plan

来确定查询问题

答案 1 :(得分:0)

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

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)上建立索引。假设uidusers中是唯一的,这对我来说很有意义。

如果您真的很关心平均值的格式,则可以:

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

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