如何解决使用
 ODPS聚合函数时执行结果爆炸问题
 知途网
 是阿里云在线学习平台,教学答疑中为大家提供使用阿里云产品遇到问题的解决方案,下面
 知途网
 将为大家讲解一下,如何解决使用
 ODPS
 聚合函数时执行结果爆炸问题。
 
 ODPS
 官方文档上提供了非常丰富的聚合函数,例如
 wm_concat,sum,count 
 等等。
 
 举个例子,会员(
 user[userid,username]
 )和购买记录(
 trade[tradeid,userid,payment,item_title]
 )是一对多的关系。对这两张表以会员的维度进行聚合组合的记录为
 user_trade[userid,username,payment_sum,item_titles],item_titles
 这个字段是用
 wm_concat(distinct trade.item_title)
 以
 userid
 分组聚合而成的,
 SQL
 如下:
 
[table=454,#FEFEFE,,1][tr][td]
 SELECT userid,username,wm_concat(DISTINCT‘,’,item_title) as item_titles
 FROM user u
 INNER JOIN trade t ON (u.userid =t.userid)
 GROUP BY u.userid,u.username
[/td][/tr][/table]
 正常情况下,一个用户不会超过几十笔购买记录。但是,不得不承认林子大了什么鸟都会有,就有这样一些奇葩用户,有上万笔购买记录。导致
 ODPS
 脚本执行得非常慢,而且最终统计结果超过
 ODPS
 限定的字符串长度上限而使整个计算过程失败。
 
 解决办法是需要将这些奇葩用户在计算之前先过滤掉,在计算之前先需要生成一张中间表用来表示所有合法的用户
 id
 集合,中间表
 SQL
 如下:
 
[table=454,#FEFEFE,,1][tr][td]
 CREATE TABLE tmp_user_filter AS
 SELECT tt.userid
 FROM(
 SELECT userid ,count(t.tradeid) as tcount
 FROM user u INNER JOIN user_trade tON(u.userid = t.userid)
 GROUP BY u.userid )tt
 WHERE tt.tcount < 200
[/td][/tr][/table]
 通过这个
 SQL
 创建了一个临时表,将所有所有交易笔数少于
 200
 笔交易的用户过筛出来,当然这个
 200
 这个阀值可以按照业务的需要进行调节。之后在其他脚本中可以与
 tmp_user_filter
 这个表进行
 INNER JOIN
 ,再用聚合函数统计,那就保证不会聚合爆炸了。
 
 改造后的
 SQL
 如下:
 
[table=454,#FEFEFE,,1][tr][td]
 SELECT userid,username,wm_concat(DISTINCT‘,’,item_title) as item_titles
 FROM user u
 INNER JOIN tmp_user_filter f ON (u.userid= f.userid)
 INNER JOIN trade t ON (u.userid =t.userid)
 GROUP BY u.userid,u.username
[/td][/tr][/table]
 
以上就是
知途网
为大家整理的解决使用
ODPS
聚合函数时执行结果爆炸问题,更多
ODPS
的使用问题请登录
www.chinamoocs.com 
搜索“
掌握开放式数据处理服务
ODPS
”课程了解。