hive针对count(distinct xxx)只产生一个reduce的优化。
0x00 造成的原因
由于使用了distinct,导致在map端的combine无法合并重复数据;对于这种count()全聚合操作时,即使设定了reduce task个数,set mapred.reduce.tasks=100;hive也只会启动一个reducer。这就造成了所有map端传来的数据都在一个tasks中执行,成为了性能瓶颈。
0x01 解决方式一(分治法)
该方法优势在于使用不同的reducer各自进行COUNT(DISTINCT)计算,充分发挥hadoop的优势,然后进行求和,间接达到了效果。需要注意的是多个tasks同时计算产生重复值的问题,所以分组需要使用到目标列的子串。
1 | SELECT |
经过验证,该方法在5000万数据量的情况下,不优化需要5分钟,经过优化需要3分钟,还是有一定的提升的。
0x10 解决方式二(随机分组法)
核心是使用group by替代count(distinct)。
1 | SELECT--3 |
- 1层使用随机数作为分组依据,同时使用group by
保证去重
。 - 2层统计各分组下的统计数。
- 3层对分组结果求和。
经过验证,该方法在5000万数据量的情况下,不优化需要5分钟,经过优化需要2.5分钟,有进一步提升。