如何解决使用
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
”课程了解。