简体   繁体   中英

How can i do this query faster? (postgreSQL)

Target - Day_1 Rolling retention in %

Questions:

1) how can i speed up this query?

2) this conversation to numeric is slow down query?

3) do i have any other options to round() it somehow else? 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.

if reg_time is an indexed column, enclosing reg_time with date function breaks indexed search. You need to consider not to use date(reg_time)

you can also identify your query issues by using 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) . This assumes that uid is unique in users , which makes sense to me.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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