Hive调优——count distinct替换

   离线数仓开发过程中经常会对数据去重后聚合统计,而对于大数据量来说,count(distinct ) 操作消耗资源且查询性能很慢,以下是调优的方式。

解决方案一:group by 替代

原sql 如下:

#=====7日、14日的app点击的用户数(user_id去重统计)
select
    group_id,
    app_id,
-- 7日内UV
    count(distinct case when dt >= '${7d_before}' then user_id else null end)  as 7d_uv, 
--14日内UV
    count(distinct case when dt >= '${14d_before}' then user_id else null end) as 14d_uv 
from tbl
where dt >= '${14d_before}'
group by group_id, --渠道
         app_id;  --app

优化思路:group by先去重,后聚合统计

#=====7日、14日的app点击的用户数(user_id去重统计)
select
    group_id,
    app_id,
-- 7日内UV
    sum(case when 7d_cnt > 0 then 1 else 0 end) as 7d_uv,
--14日内UV
    sum(case when 14d_uv > 0 then 1 else 0 end) as 14d_uv

from (select
          group_id,
          app_id,
          -- 7日内各渠道各app下的每个用户的点击量
          count(case when dt >= '${7d_before}' then user_id else null end)  as 7d_cnt,
          -- 14日内各渠道各app下的每个用户点击量
          count(case when dt >= '${14d_before}' then user_id else null end) as 14d_uv
      from tbl
      where dt >= '${14d_before}'
      group by group_id,
               app_id,
               user_id) tmp1
group by group_id,
         app_id;

方案一弊端:数据倾斜

  解决方案一通过两阶段的group by(分组聚合) 对count (distinct) 进行改造调优,需要注意的是:group by底层会走shuffle,会有数据倾斜的风险,因此方案一还可以进一步优化,待补充!

参考文章:

别再使用count distinct了_避免使用count distinct-CSDN博客

你可能感兴趣的:(#,Hive,hive,数据仓库)