簡體   English   中英

如何提高此 SQL 的速度?

[英]How to improve this SQL for speed?

我制作了這個 SQL 代碼,它工作正常,但需要 2 分鍾才能加載。 我想在獲得更快的代碼方面變得更好。 這段代碼為 2019 年每個季度的用戶活動計數和邀請構建了一個條形圖/計數。你可以看到我必須定義那一年的每個季度,這並不理想,因為我必須在把更多的季度! 請問如何改進此代碼? 謝謝!


WITH teams AS (SELECT cc.id , cc.name as company_name,clg.id as team_id, 
(select count(*) from companies_learnergroup clg where clg.company_id = cc.id) as number_of_teams_in_company, clg.name as team_name, clg.location_address,
(select count(*) from auth_user u where u.company_id = cc.id) as company_user_count,
(select count(*) from auth_user u where u.team_id = clg.id) as team_user_count,
(select count(*) from auth_user u where u.team_id = clg.id AND  ((u.last_activity BETWEEN 'January 01, 2019, 00:00 AM' AND 'March 31, 2019, 11:59 PM') or (u.last_login BETWEEN 'January 01, 2019, 00:00 AM' AND 'March 31, 2019, 11:59 PM'))) as active_users_q1_2019,
(select count(*) from auth_user u, companies_invitation ci where ci.learner_group_id = clg.id  and u.id = ci.inviter_id and ci.learner_group_id = u.team_id and ci.created_at BETWEEN 'January 01, 2019, 00:00 AM' AND 'March 31, 2019, 11:59 PM') as number_of_users_invited_to_team_by_user_in_same_team_in_q1_2019, 
(select count(*) from auth_user u where u.team_id = clg.id and (u.last_activity BETWEEN 'April 01, 2019, 00:00 AM' AND 'June 30, 2019, 11:59 PM') or (u.last_login BETWEEN 'April 01, 2019, 00:00 AM' AND 'June 30, 2019, 11:59 PM'))) as active_users_q2_2019,
(select count(*) from auth_user u, companies_invitation ci where ci.learner_group_id = clg.id  and u.id = ci.inviter_id and ci.learner_group_id = u.team_id  and ci.created_at BETWEEN 'April 01, 2019, 00:00 AM' AND 'June 30, 2019, 11:59 PM') as number_of_users_invited_to_team_by_user_in_same_team_in_q2_2019, 
(select count(*) from auth_user u where u.team_id = clg.id and (u.last_activity BETWEEN 'July 01, 2019, 00:00 AM' AND 'September 30, 2019, 11:59 PM') or (u.last_login BETWEEN 'July 01, 2019, 00:00 AM' AND 'September 30, 2019, 11:59 PM'))) as active_users_q3_2019,
(select count(*) from auth_user u, companies_invitation ci where ci.learner_group_id = clg.id  and u.id = ci.inviter_id and ci.learner_group_id = u.team_id and ci.created_at BETWEEN 'July 01, 2019, 00:00 AM' AND 'September 30, 2019, 11:59 PM') as number_of_users_invited_to_team_by_user_in_same_team_in_q3_2019, 
(select count(*) from auth_user u where u.team_id = clg.id  AND  ((u.last_activity BETWEEN 'October 01, 2019, 00:00 AM' AND 'December 31, 2019, 11:59 PM') or (u.last_login BETWEEN 'October 01, 2019, 00:00 AM' AND 'December 31, 2019, 11:59 PM'))) as active_users_q4_2019,
(select count(*) from auth_user u, companies_invitation ci where ci.learner_group_id = clg.id  and u.id = ci.inviter_id and ci.learner_group_id = u.team_id and ci.created_at BETWEEN 'October 01, 2019, 00:00 AM' AND 'December 31, 2019, 11:59 PM') as number_of_users_invited_to_team_by_user_in_same_team_in_q4_2019, 
cc.created_at as company_account_created, 
clg.created as team_account_created, cc.office_location, cc.region_of_responsibility, cc.company_type,
cc.company_url,  string_agg(ctag.name, ', ') as retailer_tags FROM companies_company cc
JOIN companies_learnergroup clg on clg.company_id = cc.id
JOIN company_companytag cctag ON cc.id = cctag.company_id
JOIN companies_tag ctag ON ctag.id = cctag.tag_id
WHERE cc.company_type = 'retailer'
and cc.deactivated is null
GROUP BY cc.id, cc.name, clg.id
ORDER BY cc.id) 
     
    SELECT COUNT(*) as "Amount", '2019 Q1 Retailer teams with at least 1 active user and at least 1 invite sent from user in same team' as "Filter" FROM teams 
    WHERE active_users_q1_2019 > 0 AND number_of_users_invited_to_team_by_user_in_same_team_in_q1_2019 > 0
   
    
    UNION
    SELECT COUNT(*) as "Amount", '2019 Q2 Retailer teams with at least 1 active user and at least 1 invite sent from user in same team' FROM teams 
    WHERE active_users_q2_2019 > 0 AND number_of_users_invited_to_team_by_user_in_same_team_in_q2_2019 > 0
    

    
    UNION
    SELECT COUNT(*) as "Amount", '2019 Q3 Retailer teams with at least 1 active user and at least 1 invite sent from user in same team' FROM teams 
    WHERE active_users_q3_2019 > 0 AND number_of_users_invited_to_team_by_user_in_same_team_in_q3_2019 > 0
   
    
    UNION
    SELECT COUNT(*) as "Amount", '2019 Q4 Retailer teams with at least 1 active user and at least 1 invite sent from user in same team in Q4 2019' FROM teams 
    WHERE active_users_q4_2019 > 0 AND number_of_users_invited_to_team_by_user_in_same_team_in_q4_2019 > 0
    

    
) funnel
ORDER BY "Filter"`

   

與性能沒有直接關系,除了發布的查詢未運行。 它包含缺少的第 7 和第 9 選擇的左括號。 and (u.last_activity ...應該是and ((u.last_activity ... 。因為它在第 5 次和第 11 次選擇中,也) funnel產生錯誤。但我只會考慮這些並在構建帖子時.
最大的問題是您的BETWEEN語句不起作用,它們會運行但不會產生正確的結果。 這是因為您正在對 MONTH 名稱進行文本比較。 不幸的是,由於文本比較,Postgres 對日歷一無所知。 假設 u.last_activity 實際上包含一個日期,您可以通過extract('quarter' from u.last_activity)直接獲取季度。 如果它不是日期(時間戳),那么更改數據模型也許還為時不晚。 通過文本比較查看哪個季度得到哪個月份的演示 另見Postgres 摘錄

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM