摘要:本篇教程介绍了大数据统计分析 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)也可统计总数。
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标大数据云计算大数据分析频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号