一次HIVE SQL数据倾斜问题的解决

132 阅读2分钟

如下SQL:

select 
    a, 
    b, 
    sum(c)
from 
    table_name
where _date='2019-05-01'
group by
    a,b 

hive执行到某个stage一直卡着进度不动

最后判断原因应该就是group by的数据倾斜,数据探查发现,a,b分组后大部分count(*)都是个位数,有一部分是几百几千,怀疑是这块导致的数据倾斜。

但是,在where条件中排除了这部分count(*)很多的数据依然很慢。

最终使用以下SQL解决了:

SELECT
 a,
 b,
 sum_c
FROM
 (
  select
   a,
   b,
   SUM(c) OVER(PARTITION BY a, b) sum_c
  from
   table_name
  where
   _date = '2019-05-01'
 ) t
group by
 a,
 b,
 sum_c

原始的查询中,直接按照ab进行分组并求和,ab的组合值分布不均匀,某些组合出现的频率远高于其他组合,使得这些组合的数据集中在少数几个reduce任务中,从而拖慢整个查询的速度。

而使用了OVER(PARTITION BY a, b)的查询方式后:

  1. 内部子查询中使用的SUM(c) OVER(PARTITION BY a, b)窗口函数会在每个由ab确定的分组内,预先计算c的总和。这样做的好处是,将原本大量的原始数据在每个分组内进行了部分聚合,得到了每个分组对应的总和值sum_c

  2. 在外部查询中,再按照absum_c进行分组。此时,数据的分布相对更加均匀,因为之前已经在分组内进行了部分聚合,减少了每个分组的数据量差异。

这样一来,在进行最终的分组操作时,每个分组的数据量相对较为均衡,不会出现少数分组包含大量数据的情况,从而缓解了数据倾斜问题,提高了查询的执行效率。