即使调整set mapred.reduce.tasks=100参数也不会实际影响Reduce Task个数,Hive运行时输出“Number of reduce tasks determined at compile time: 1”。原来Hive在处理COUNT这种“全聚合(full aggregates)”计算时,它会忽略用户指定的Reduce Task数,而强制使用1
写法一:每天去重到细粒度的(日),再聚合到粗粒度(月)
selectcount(distinct uuid)from(select partition_date,uuid
from detail_sdk_session t
where t.partition_date >='2023-02-01'and t.partition_date <='2023-02-28'groupby partition_date,uuid
)t
;
解析
每天去重到细粒度的(日),再聚合到粗粒度(月)
写法二:先聚合到细粒度的(同一特征),再聚合到粗粒度(所有)
-- 外层SELECT求和selectsum(mau_part) mau
from(-- 内层select分别进行count(distinct)计算select
substr(uuid,1,3) uuid_part -- 这里数据量越大,可以切的位数越长,count(distinct substr(uuid,4))as mau_part
from test
groupby substr(uuid,1,3),hash(uuid)%50) t
;
-- 第三层:对所有分组进行求和。selectsum(s.mau_part) mau
from(-- 第二层:按照标记进行分组,统计每个分组下uuid的个数。select
tag
,count(*) mau_part
from(-- 第一层:对uuid进行去重,并为去重后的uuid打上整数标记。select
uuid
,cast(rand()*100asint) tag -- 为去重后的uuid打上标记,标记为:0-100之间的整数。这里数据量越大,可以标记范围越大from test
groupby uuid -- 通过group by,保证去重) t
groupby tag
) s
;
第一层select:对uuid进行去重,并为去重后的uuid打上整数标记
第二层select:按照标记进行分组,统计每个分组下uuid的个数
第三层select:对所有分组进行求和
上面这个方法最关键的是为每个uuid进行标记,这样就可以对其进行分组,分别计数,最后去和。如果数据量确实很大,也可以增加分组的个数。例如:cast(rand() * 100 as int) as tag