【问题标题】:How to optimize subquery如何优化子查询
【发布时间】:2019-10-07 10:31:28
【问题描述】:

我有一个包含多个子查询的查询来计算有多少用户参与了某个事务,具体取决于状态。

SELECT * FROM (
    SELECT
    DATE(changes.created_at) AS `date`,
    SUM(IF(changes.status = 15, 1, 0)) AS installed_daily,
    SUM(IF(changes.status = 3, 1, 0)) AS port_reserved,
    (
      SELECT COUNT(DISTINCT created_by) FROM applicant_state_changes
      WHERE DATE(created_at) = DATE(changes.created_at) AND status = 3
    ) AS user_port_reserved,
    SUM(IF(changes.status = 5, 1, 0)) AS document_validated,
    (
      SELECT COUNT(DISTINCT created_by) FROM applicant_state_changes
      WHERE DATE(created_at) = DATE(changes.created_at) AND status = 5
    ) AS user_document_validated,
    SUM(IF(changes.status = 7, 1, 0)) AS account_created,
    (
      SELECT COUNT(DISTINCT created_by) FROM applicant_state_changes
      WHERE DATE(created_at) = DATE(changes.created_at) AND status = 7
    ) AS user_account_created,
    SUM(IF(changes.status = 11, 1, 0)) AS jo_created,
    (
      SELECT COUNT(DISTINCT created_by) FROM applicant_state_changes
      WHERE DATE(created_at) = DATE(changes.created_at) AND status = 11
    ) AS user_jo_created
    FROM applicant_state_changes AS changes
    GROUP BY DATE(changes.created_at)
    LIMIT 100 OFFSET 0
) a
ORDER BY date ASC;

这大约需要 130 秒。如果没有子查询,我的查询最多只需要 0.5 秒。

【问题讨论】:

    标签: mysql select count distinct


    【解决方案1】:

    你可以在表达式中使用条件聚合

     SELECT
        DATE(changes.created_at) AS `date`,
        SUM(IF(changes.status = 15, 1, 0)) AS installed_daily,
        SUM(IF(changes.status = 3, 1, 0)) AS port_reserved,
        count(distinct case when status = 3 then created_by end) as user_port_reserved
        ,
        SUM(IF(changes.status = 5, 1, 0)) AS document_validated,
        count(distinct case when status = 5 then created_by  end) AS user_document_validated,
        SUM(IF(changes.status = 7, 1, 0)) AS account_created,
        count(distinct case when status = 7 then 1 end) AS user_account_created,
        SUM(IF(changes.status = 11, 1, 0)) AS jo_created,
        count(distinct case when status = 11 then created_by  end) AS user_jo_created
        FROM applicant_state_changes AS changes where 
        GROUP BY DATE(changes.created_at)
        LIMIT 100 OFFSET 0
    

    【讨论】:

    • 问题是我在计算 DISTINCT created_by。
    • @SeeMore,我已经改了-你现在可以查看
    • 谢谢。结果持续时间现在为 0.5 秒。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    • 2018-04-20
    • 2011-06-09
    • 2011-02-11
    • 1970-01-01
    相关资源
    最近更新 更多