去重指标增量计算优化

2020-01-11  本文已影响0人  黑曼巴yk

背景

在开发时候经常需要统计最近N天数据,用户数目去重等统计指标

select visitor_id
from 
  (  
    select item_id, count(distinct visitor_id) as ipv_uv_1d_001
    from crm_bi.log_vst_di
    where ds <= '${bizdate}'
    and ds >= to_char(dateadd(to_date('${bizdate}','yyyymmdd'),-29,'dd'),'yyyymmdd')
     group by item_id
  ) a

上面可能会造成严重问题,需要的Map instance数目太多。超过99999个限制。为什么Instance个数需要那么多呢?原因:每天的日志数据很大,30天的数据量更是惊人,这时候Select 操作需要大量的Map Instance,结果查过了Instance的上限,代码无法运行

目的

如何计算长周期的指标,又不影响性能呢?

  1. 多天汇总的问题根源在数据量问题,如果把数据量降低,就可以解决
  2. 减少数据量最直接办法就是把每天的数据量都减少,因此需要构建临时表,对1d的数据进行轻度汇总,这样就能去掉很多重复数据 ,减少数据量。

方案

  1. 构建中间表,每天汇总一次
  2. 计算多天的数据,依赖中间表进行汇总
insert overwrite table demo_itm_visitor_xx(ds='${bizdate}')
select item_id, visitor_id
from (
  select  item_id, visitor_id
  from crm_bi.log_vst_di
  where ds='${bizdate}'
  group by item_id, visitor_id 
) a

对demo_itm_visitor_xx表进行30天汇总

select visitor_id
from
    (select   item_id
             ,count(distinct visitor_id) as ipv_uv_1d_001
     from     demo_itm_visitor_xx
     where    ds <= '{bizdate}'
     and      ds >= to_char(dateadd(to_date('${bizdate}','yyyymmdd'),-29,'dd'),'yyyymmdd')
     group by item_id
    ) a

思考

上面方法优点是提高了性能,缺点是每次计算多天的数据时候,都要N个分区的数据那么是否有一种方法,不需要计算,已经有一个存放最近N天数据的

增长累计方式计算长周期指标

例子: 求最近1天店铺的老访客数,老访客定义为:最近180天有访问,就算老访客
思路:

  1. 将买家从前天开始往前推180天,记做集合A;也就是说从-180到-1的访客数据都在集合A中了
    更新公式为:An=An-1+Ao-A ,即今天的nd数据=历史全量数据+今天的增量数据-最老那天的增量数据

  2. 使用集合A和昨天的访客做Join操作。如果在集合A中,则是老访客,否则是新访客。

上一篇下一篇

猜你喜欢

热点阅读