简体   繁体   English

我怎样才能更快地查询? (PostgreSQL系统)

[英]How can i do this query faster? (postgreSQL)

Target - Day_1 Rolling retention in % 目标-第1天的滚动保留率(%)

Questions: 问题:

1) how can i speed up this query? 1)我如何加快查询速度?

2) this conversation to numeric is slow down query? 2)此会话对数字是否减慢查询?

3) do i have any other options to round() it somehow else? 3)我还有其他选择来回圆()吗? or it's optimal? 还是最佳?

Query: 查询:

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

reg_time is enclosed with date function. reg_time包含在date函数中。

if reg_time is an indexed column, enclosing reg_time with date function breaks indexed search. 如果reg_time是索引列,则使用date函数将reg_time括起来会中断索引搜索。 You need to consider not to use date(reg_time) 您需要考虑不要使用date(reg_time)

you can also identify your query issues by using SQL Explain Plan 您还可以使用SQL Explain Plan来确定查询问题

With the right indexes, I suspect this will be faster: 使用正确的索引,我怀疑这会更快:

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;

You want indexes on users(reg_time) and dailyusers(uid, day) . 您想要在users(reg_time)dailyusers(uid, day)上建立索引。 This assumes that uid is unique in users , which makes sense to me. 假设uidusers是唯一的,这对我来说很有意义。

If you really care about the format of the average, then you can do: 如果您真的关心平均值的格式,则可以执行以下操作:

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

This is the best I can do with the query you have given. 这是我所能提供的最佳查询。 There may be a better way to write the query. 可能有更好的方式编写查询。 I would suggest you ask another question with sample data, desired results, and an explanation of what the query is doing (or supposed to be doing), if you want help with that. 如果您需要帮助,我建议您提出另一个问题,其中包括示例数据,所需结果以及对查询正在执行(或应该执行)的解释。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM