为什么在Hive中,使用count(distinct)比group by慢?

17

在Hive中,我相信count(distinct)比group-by更容易导致reducers的工作负载不平衡,最终只有一个reducer在努力。以下是示例查询。

为什么会这样呢?

示例查询:

select count(distinct user)
from some_table

按组别分组的版本(建议更快):

select count(*) from
(select user
 from some_table
 group by user) q
注意:第26张幻灯片在这个演示文稿中描述了这个问题。

我不明白你的问题。你是在问为什么“group by”版本更快吗?如果是的话,那你为什么认为它更快呢?你是在某个地方读到的还是亲眼看到它表现出来的? - Hari Menon
1个回答

21
select count(distinct user)
from some_table;

该查询在Map端进行计数。每个Mapper发出一个值,即计数。然后需要聚合所有值以生成总计数,这是单个Reducer的工作。

select count(*) from
(select user
 from some_table
 group by user) q;

这个查询有两个阶段。在第一阶段,对于每个用户,GROUP BY 在地图端聚合用户并发出一个值。然后在 reduce 端必须再次进行聚合,但可以使用多个 reducer。在第二阶段,COUNT 在地图端执行,然后最终结果使用一个单独的 reducer 进行聚合。

因此,如果您有大量的地图端分割,则第一个查询将不得不聚合大量的值结果。第二个查询可以在第一阶段的 reduce 端使用多个 reducer,然后在第二阶段中,最后只需要一个 reducer 就可以了。

通常情况下,这不是优化。您必须拥有大量分割才能使查询 1 的 reducer 成为问题。第二个查询有两个阶段,仅这一点就比查询 1 慢(第二阶段无法开始直到第一阶段完全完成)。因此,尽管我可以理解某些建议的原因,但除非进行适当的测量并显示改进,否则我会持怀疑态度。


1
在Hive1.1中,这两个查询的解释结果相同。它们都只有一个阶段。 - Harper Koo
点赞你的回答。一个大表的例子是:如果有很少的不同值,那么第一种选项可能比第二种运行得更快,因为大多数分组都在映射端完成。 - Keith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接