Count(Distinct)只会开启一个reduce.如果数据量大的话,这个Job很难完成。
数据量小的时候无所谓,数据量大的情况下,由于 COUNT DISTINCT 操作需要用一个 Reduce Task 来完成,这一个 Reduce 需要处理的数据量太大,就会导致整个 Job 很难完成, 一般 COUNT DISTINCT 使用先 GROUP BY 再 COUNT 的方式替换,但是需要注意 group by 造成 的数据倾斜问题.
(1)案例实操
1)创建一张大表
hive (default)> create table bigtable(id bigint, time bigint, uid string, keyword string, url_rank int, click_num int, click_url string) row format delimited fields terminated by 't';
(2)加载数据
hive (default)> load data local inpath '/opt/module/data/bigtable' into table bigtable;
(3)设置 5 个 reduce 个数
set mapreduce.job.reduces = 5;
(4)执行去重 id 查询
hive (default)> select count(distinct id) from bigtable;
(5)采用 GROUP by 去重 id
hive (default)> select count(id) from (select id from bigtable group by id) a;
总结:
在数据量比较大的情况下,要做去重,是不建议采用count(distinct)去做去重,
count(distinct)只会开启一个reduce来进行输出的,会发生数据倾斜。这个时候建议采用的是group by的方法来做处理。采用group by的话,group by 的字段会作为key,这个key会被分配到不同的reduce里面,在每个reduce里面做并行去重,最后再聚合输出。 虽然会多用一个 Job 来完成,但在数据量大的情况下,这个绝对是值得的。


![Hive-优化调优[(Count(Distinct)去重统计] Hive-优化调优[(Count(Distinct)去重统计]](http://www.mshxw.com/aiimages/31/342685.png)
