我在a question上读过:
--我遇到了一个计算独立计数的Hive查询,没有分组,运行非常慢。所以我想知道这个功能是如何在Hive中实现的,这里有一个UDAFCountDistinct吗?
答案是:
为了实现计数不同,蜂巢依赖于GenericUDAFCount。联合国非洲发展新议程没有专门为计数不同而实施。这些“不同的”键将是MapReduce混乱阶段的分区键的一部分,这样它们就很自然地被“区分”了。
根据您的情况,它运行缓慢,因为只有一个减速机来处理大量的详细数据。您可以在计数前使用组来获得更多的并行性:
select count(1) from (select id from tbl group by id) tmp;然而,我不明白以下几点:
发布于 2020-01-24 16:31:02
我会尽力解释的。
第1部分:
的答案是什么意思“那些‘不同的’键将是MapReduce混乱阶段的分区键的一部分”?你能再解释一下吗?
GenericUDAFCount具有count和count distinct两种功能。如何实现count distinct
?
让我们以下面的查询为例:
select category, count(distinct brand) from market group by category;将为此查询启动一个MapReduce作业。
distinct-by键是count(distinct ...中的表达式(列),在本例中是brand。
partition-by键是用于计算map阶段记录的哈希代码的字段。然后使用这个散列值来决定一个记录应该去哪个分区。通常,partition-by键位于SQL查询的group by部分。在这种情况下,它是category。
映射器的实际output-key将是partition-by键和distinct-by键的组合。对于上述情况,映射器的输出键可能类似于(饮料、百事可乐)。
该设计使具有相同group-by键的所有行都落入同一减速器中。
映射器输出的value部分在这里并不重要。
稍后,根据sort-by键对记录进行排序,这与output key相同。
然后在reduce阶段,在每个单独的减速机上,所有记录首先按类别排序,然后按品牌排序。这使得很容易获得count(distinct )聚合的结果。每个不同的(类别,品牌)对保证只处理一次。聚合已在每个组中转换为一个count(*)。调用reduce方法的输入键将是这些不同的对之一。减速机过程跟踪复合键。每当类别部分发生变化时,我们就知道有一个新的组出现了,我们开始从1开始计算这个组。
第2部分:
为什么在这种情况下只有一种减速器?在没有像这样的
count distinct计算group by时:
select count(distinct brand) from market只有一个减速机承担所有的工作。为什么?因为partition-by键不存在,或者我们可以说所有记录都有相同的哈希码。所以它们会掉进同一个减速器里。
第3部分:
为什么奇怪的内部查询会导致更多的分区?
内部查询的partition-by键是group by键id。id值的分布很可能是均匀的,因此记录由许多不同的还原器处理。然后,在内部查询之后,可以安全地得出结论,所有的id都是不同的。所以现在只需要一个简单的count(1)。
但请注意,输出将只启动一个减速机。为什么它不受苦?由于count(1)不需要详细的值,地图端的聚合极大地减少了还原器处理的数据量。
还有一点,这种重写不能保证表现得更好,因为它引入了额外的MR阶段。
https://stackoverflow.com/questions/59885052
复制相似问题