长周期指标的计算优化方案

原文地址

1 背景

在电子商务公司(如淘宝),对用户的数据分析的角度和思路可谓是应有尽有、层出不穷。所以在电商数据仓库和商业分析场景里,经常需要计算最近N天访客数、最近N天的购买用户数、老客数等等类似的指标。这些指标有一个共同点:都需要根据用户在电商平台上(或网上店铺)一段时间积累的数据进行计算(这里讨论的前提是数据都存储在MaxCompute上)。
一般情况下,这些指标的计算方式就是从日志明细表中计算就行了,如下代码计算商品的最近30天访客数:

select   item_id         --商品id
     ,count(distinct visitor_id) as ipv_uv_1d_001
from     用户访问商品日志明细表
where    ds <= ${bdp.system.bizdate}
and ds >=to_char(dateadd(to_date(${bdp.system.bizdate},‘yyyymmdd‘),-29,‘dd‘),‘yyyymmdd‘)
 group by item_id

??但是当每天的日志量很大时,上面代码存在一个严重的问题,需要的**Map Instance**个数太多,甚至会超过**99999**个Instance个数的限制,Map Task就没有办法顺利执行,更别说后续的操作了。为什么Instance个数需要那么多呢?原因:每天的日志数据很大,30天的数据量更是惊人。这时候Select 操作需要大量的Map Instance,结果查过了Instance的上限,代码无法运行

2 目的

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

??1. 多天汇总的问题根源是数据量的问题,如果把数据量给降低了,就可以解决这个问题了。

??2. 减少数据量最直接的办法是把每天的数据量都给减少,因此需要构建临时表,对1d的数据进行轻度汇总,这样就能去掉很多重复数据,减少数据量。

3 方案

??1. 构建中间表,每天汇总一次,比如对于上面的例子,构建一个item_id+visitor_id粒度的中间表

??2. 计算多天的数据,依赖中间表进行汇总

??例子如下:

?? step1:构建item_id+visitior_id粒度的日汇总表,记作A

insert overwrite table mds_itm_vsr_xx(ds=‘${bdp.system.bizdate} ‘)
select item_id,visitor_id,count(1) as pv
from
    (
     select   item_id,visitor_id
     from     用户访问商品日志明细表
     where    ds =${bdp.system.bizdate}
     group by item_id,visitor_id
    )a

??**setp2:对A进行30天汇总**

   select   item_id
            ,count(distinct visitor_id) as uv
            ,sum(pv) as pv
     from      mds_itm_vsr_xx
     where    ds <= ‘${bdp.system.bizdate} ‘
     and      ds >= to_char(dateadd(to_date(‘${bdp.system.bizdate} ‘,‘yyyymmdd‘),-29,‘dd‘),‘yyyymmdd‘)
     group by item_id

4 影响及思考

??上面讲述的方法,对每天的访问日志明细数据进行单天去重,从而减少了数据量,提高了性能。缺点是每次计算多天的数据的时候,都要N个分区的数据,那么能不能有一种方式,不需要读取N个分区的数据,而是把N个分区的数据压缩合并成一个分区的数据,让一个分区的数据包含历史数据的信息。业务上是有类似场景的,有如下方式:

1. 增量累计方式计算长周期指标

??例子:求最近1天店铺商品的老买家数,老买家数的算法定义为:过去一段时间有购买的买家(比如过去30天)。
一般情况下,老买家数计算方式:

select   item_id         --商品id
       ,buyer_id as old_buyer_id
from     用户购买商品明细表
where    ds < ${bdp.system.bizdate}
and ds >=to_char(dateadd(to_date(${bdp.system.bizdate},‘yyyymmdd‘),-29,‘dd‘),‘yyyymmdd‘)
 group by item_id
        ,buyer_id

??改进思路:
?? 1. 维护一张店铺商品和买家购买关系的维表记作表A,记录买家和店铺的购买关系,以及第一次购买时间,最近一次购买时间,累计购买件数,累计购买金额等等信息
?? 2. 每天使用最近1天的支付明细日志更新表A的相关数据
?? 3. 计算老买家时,最需要判断最近一次购买时间是否是30天之内就行了,从而做到最大程度上的数据关系对去重,减少了计算输入数据量

原文地址

时间: 2024-10-25 20:33:46

长周期指标的计算优化方案的相关文章

百万级数据库优化方案数据库SQL优化大总结

一.百万级数据库优化方案 1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 最好不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库. 备注.描述.评论之类的可以设置为 NULL,其他的,最好不要使用NULL. 不要以为 NULL 不需要空间,

web前端优化方案(Yahoo)

目录(分7类,共35条): [内容]尽量减少HTTP请求数    [服务器]使用CDN(Content Delivery Network)    [服务器]添上Expires或者Cache-Control HTTP头    [服务器]Gzip组件    [css]把样式表放在顶部    [js]把脚本放在底部    [css]避免使用CSS表达式    [js, css]把JavaScript和CSS放到外面    [内容]减少DNS查找    [js, css]压缩JavaScript和CSS

Mysql 优化方案

Mysql 优化方案 从开发角度优化mysql,让数据库效率更高.更快. 索引优化 查看mysql状态 通过周期性观察mysql状态优化,更有利于确定mysql性能瓶颈在哪里. 通过 show status 命令观察mysql的运行状态.其中比较主要的几个: 命令格式: show [global|session] status like 'command'; 默认是session: 当前会话:global: 全局会话. show status like "up_time"; 查看mys

H5性能优化方案

H5性能优化意义 对于一个H5的产品,功能无疑很重要,但是性能同样是用户体验中不可或缺的一环.原本H5的渲染性能就不及native的app,如果不把性能优化做起来,将极大地影响用户使用产品的积极性. 用户感受 当用户能够在1-2秒内打开H5页面,看到信息的展示,或者能够开始进行下一步的操作,用户会感觉速度还好,可以接受:而页面如果在2-5秒后才进入可用的状态,用户的耐心会逐渐丧失:而如果一个界面超过5秒甚至更久才能显示出来,这对用户来说基本是无法忍受的,也许有一部分用户会退出重新进入,但更多的用

Unity学习-优化_卡顿原因定位以及优化方案

除了Unity的一些组件优化技巧之外,更多的细节处于代码层面上 最近学习优化,看到一篇文章,写的很详细,从底层原理到我们 的实际处理,都有一些非常好的建议,可以推荐给小伙伴们看看 https://www.jianshu.com/p/289de89a6609 ===========如何定位程序的哪一个环节产生了过大的开销============ 使用Uinty的Profiler工具,可以比较精准快速的定位程序的哪一个位置产生了大开销 首先在build setting里面勾选Autoconnect

mysql 性能优化方案 (转)

网 上有不少MySQL 性能优化方案,不过,mysql的优化同sql server相比,更为麻烦与复杂,同样的设置,在不同的环境下 ,由于内存,访问量,读写频率,数据差异等等情况,可能会出现不同的结果,因此简单地根据某个给出方案来配置mysql是行不通的,最好能使用 status信息对mysql进行具体的优化. mysql> show global status; 可以列出mysql服务器运行各种状态值,另外,查询mysql服务器配置信息语句: mysql> show variables; 一

[转] 钉钉的H5性能优化方案

对于一个H5的产品,功能无疑很重要,但是性能同样是用户体验中不可或缺的一环.原本H5的渲染性能就不及native的app,如果不把性能优化做起来,将极大地影响用户使用产品的积极性. 用户感受 当用户能够在1-2秒内打开H5页面,看到信息的展示,或者能够开始进行下一步的操作,用户会感觉速度还好,可以接受:而页面如果在2-5秒后才进入可用的状态,用户的耐心会逐渐丧失:而如果一个界面超过5秒甚至更久才能显示出来,这对用户来说基本是无法忍受的,也许有一部分用户会退出重新进入,但更多的用户会直接放弃使用.

mysql大内存高性能优化方案

mysql优化是一个相对来说比较重要的事情了,特别像对mysql读写比较多的网站就显得非常重要了,下面我们来介绍mysql大内存高性能优化方案 8G内存下MySQL的优化 按照下面的设置试试看:key_buffer = 3840Mmax_allowed_packet = 16Mtable_cache = 1024sort_buffer_size = 32Mread_buffer_size = 32Mread_rnd_buffer_size = 32Mmyisam_sort_buffer_size

地图点聚合优化方案

一.为什么需要点聚合 在地图上查询结果通常以标记点的形式展现,但是如果标记点较多,不仅会大大增加客户端的渲染时间,让客户端变得很卡,而且会让人产生密集恐惧症(图1).为了解决这一问题,我们需要一种手段能在用户有限的可视区域范围内,利用最小的区域展示出最全面的信息,而又不产生重叠覆盖. 图1 二.已尝试的方案---kmeans 直觉上用聚类算法能较好达成我们目标,因此采用简单的kmeans聚类.根据客户端的请求,我们知道了客户端显示的范围,并到索引引擎里取出在此范围内的数据,并对这些数据进行kme