大数据统计分析 Hive SQL count(distinct)效率问题及优化
沉沙 2018-09-29 来源 : 阅读 7283 评论 0

摘要:本篇教程介绍了大数据统计分析 Hive SQL count(distinct)效率问题及优化,希望阅读本篇文章以后大家有所收获,帮助大家对大数据云计算大数据分析的理解更加深入。

本篇教程介绍了大数据统计分析 Hive SQL count(distinct)效率问题及优化,希望阅读本篇文章以后大家有所收获,帮助大家对大数据云计算大数据分析的理解更加深入。

<

一个工作任务,统计一个按天分区每天都有百亿条数据条的hive表中account字段的非重用户数(大概两千万)。后来又更改为按id字段分别统计每个id的用户数。
我很轻易的跳出来了count(distinct account)这个句子。然后写上了一行查询,等待了四个小时,然后map反着跑
 就知道没这么容易的任务。。
然后想起来Hive SQL 基于的mapreduce是并行计算,百亿的数据可不是平时测试时的mysql里的几百条数据。
这么想来应该是map和reduce的内存不够,

set mapreduce.map.memory.mb=48192;
set mapreduce.reduce.memory.mb=48192;

执行语句

select count(distinct account) from...where...

继续mapreduce,三个小时后报错error in shuffle in fetcher#3. shuffle过程又出问题了。

找呀找,reducer只有1? 那还怎么并行?果断

set mapred.reduce.tasks=1000;

又进行查询,发现reducer 还是1。 只能求助于万能的Internet了。
原来因为加入distinct,map阶段不能用combine消重,数据输出为(key,value)形式然后在reduce阶段进行消重。
重点是,Hive在处理COUNT这种“全聚合(full aggregates)”计算时,它会忽略用户指定的Reduce Task数,而强制使用1。
示意图如下

解决办法:转换为子查询,转化为两个mapreduce任务  先select distinct的字段,然后在count(),这样去重就会分发到不同的reduce块,count依旧是一个reduce但是只需要计数即可。

select count(*) from (select distinct account form tablename where...)t;

这样大概半小时可以得到结果。
 
后来需求改变为对这个表按account的类型(字段名为id)统计每个类型的account非重复数。
如果按照上述方法,在查询条件添加 where id=..,这样每个查询都需要半小时,效率很低。
优化方法:利用gourp by 按id,account分组,存入一个临时表 只需要对临时表进行统计即可

insert overwrite table temp select id,account,count(1) as num from tablename group by id,account;

这样temp表里的数据直接就是非重数据,并且按id升序排序,按id筛选 count(*)即可。 sum(num)也可统计总数。
 
     

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标大数据云计算大数据分析频道!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 2 不喜欢 | 1
看完这篇文章有何感觉?已经有3人表态,67%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程