设为首页 加入收藏

TOP

Hive SQL count(distinct)效率问题及优化
2017-10-12 12:49:17 】 浏览:9901
Tags: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 countdistinct 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*fromselect 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)也可统计总数。

 

 

参考:http://blog.csdn.net/xiewenbo/article/details/29559075

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇sqlserver2008 insert语句性能 下一篇mysql 储存类型自增主键区别

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目