蜂巢计数不同的UDAF2

时间:2020-01-23 18:32:09

标签: hadoop hive

我在a question上读过:

我遇到了一个Hive查询,该查询计算没有分组的不同计数, 运行非常慢。所以我想知道此功能如何 在Hive中实施,是否为此有UDAFCountDistinct?

答案:

要获得不同的计数,Hive依赖于GenericUDAFCount。那里 没有专门针对计数不同而实施的UDAF。那些 “与众不同”键将成为 MapReduce Shuffle阶段,通过这种方式,它们可以“与众不同” 自然地。

根据您的情况,它运行缓慢,因为只有一个 减速器可处理大量详细数据。您可以使用分组方式 在获得更多并行性之前,先进行计数:

select count(1) from (select id from tbl group by id) tmp;

但是我不明白一些事情:

  1. 回答者的意思是“那些'由'区别'键将成为MapReduce Shuffle阶段的分区键的一部分”?您能解释一下吗?
  2. 为什么在这种情况下只有一个减速器?
  3. 为什么奇怪的内部查询会导致更多分区?

1 个答案:

答案 0 :(得分:1)

我会尝试解释。

第1部分:

回答者是什么意思,“那些“由...区别”键将成为MapReduce Shuffle阶段的分区键的一部分”?您能解释一下吗? UDAF GenericUDAFCount具有countcount 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方法的输入键将是这些不同对之一。 Reducer进程跟踪组合键。每当类别部分更改时,我们就会知道会有一个新的组,并且我们将从1开始对该组进行计数。

第2部分:

在这种情况下,为什么只有一个减速器? 在不使用count distinct的情况下计算group by时:

    select count(distinct brand) from market

只有一个减速器负责所有工作。为什么?因为partition-by键不存在,或者我们可以说所有记录都具有相同的哈希码。因此它们将属于同一减速器。

第3部分:

为什么奇怪的内部查询会导致更多分区?

内部查询的partition-by键是group byidid值很可能分布均匀,因此记录由许多不同的化简器处理。然后在进行内部查询之后,可以得出结论,所有id都互不相同。因此,现在只需要一个简单的count(1)
但请注意,输出将仅启动一个减速器。为什么不遭受痛苦?由于count(1)不需要详细的值,因此映射端聚合极大地减少了reducer处理的数据量。
还有一件事,由于重写会引入额外的MR阶段,因此不能保证性能会更好。

相关问题