MySQL:使用子类(子查询)聚合每周统计数据

时间:2017-02-24 15:15:46

标签: mysql sql performance

我想在MySQL-Table上收集每周静态。

表本身具有以下结构:

user_id         action_id        created
   0              123       2017-01-01 00.00:00
   0              124              ...
   1              123              ...
  ...             ...              ...

我想汇总每周静态:

  • 每周有效的用户数

    这很简单:

    SELECT 
      YEARWEEK(created) as week, 
      COUNT(DISTINCT user_id) AS count 
    FROM data 
    GROUP BY YEARWEEK(created);
    

    此外,我可以应用排序。

    结果如下:

     week       count
    201701        2
    201702        3
    
  • 第一次每周有效的用户数 我想通过使用子查询来解决它

    SELECT 
      YEARWEEK(created) as week, 
      COUNT(DISTINCT user_id) AS count,
      (
        SELECT 
          COUNT(DISTINCT d2.user_id)
        FROM data d2
        WHERE YEARWEEK(d2.created) = week
        AND NOT EXISTS (SELECT 1 FROM data d3
        WHERE YEARWEEK(d3.created) < week AND d2.user_id = d3.user_id)
      ) as countNewUsers
    FROM data d1
    GROUP BY YEARWEEK(created);
    
  • 每周有多少初级用户 在相关周之前,初级用户活跃了1到10次 与上面的类似,但与其他子查询
  • 每周有效的超级用户 高级用户在相关周之前活跃了10多次

这可以按预期工作,但性能相当差,因为在分组发生之前会对子查询进行评估。表中有数百万行,这需要很长时间。

是否有人为此查询提供了更好的解决方案,理想情况下返回单个结果集中的所有值?

1 个答案:

答案 0 :(得分:1)

我认为您的所有查询都可能来自一个“中间人”。表。它将包含(yearweek,userid,count)。

  • 每周活跃的用户:几乎相同的查询,但从此表更快。
  • 第一次激活:自我加入ON用户ID和所需的周与MIN(每周)
  • 在目标周之前使用... SUM(count) WHERE ... < week GROUP BY userid
  • 使用以上内容确定Junior / Power的用户ID。