数据倾斜之count(distinct)

一、简单count(distinct id)

count(distinct id)

在极大数据量的情况下

从执行计划上面来看:

只生成一个reducer任务,所有的id都聚集到同一个reducer任务进行去重然后在聚合,非常容易造成数据倾斜.

解决方案:

1、利用Hive对嵌套语句的支持,将原来一个MapReduce作业转换为两个作业,

在第一阶段选出全部的非重复id,在第二阶段对选出的非重复id进行计数。

在第一阶段可以通过增大Reduce的并发数,并发处理Map输出。

在第二阶段,对已去重的id进行计数,count(*)在Map阶段不需要输出原id,只输出一个计数结果。

这样即使第二阶段Hive强制指定一个Reduce Task,极少量的Map输出数据也不会使单一的Reduce Task造成oom。

select count(*) from (select distinct id from users)t;

2、group by

select a,count(distinct b) from t group by 

select tt.a,count(tt.b) from (select a,b from t group by a,b)tt group by tt.a

group by将数据分组到了多个reducer上进行处理

distinct:先把b列所有数据保存到内存,速度快,单b列的值形成为key值;

group by:把b列数据排序,空间复杂度就是O(1),时间复杂度是O(nlogn);

比较:distinct耗费内存,效率高,可能产生OOM;

     groupby,排序消耗时间更多,在时间复杂度允许下,空间复杂度更低。

    

二、多count(distinct column)

https://www.jianshu.com/p/9ecf5e96c47f

你可能感兴趣的:(数据库,java)