FAILED: SemanticException [Error 10022]: DISTINCT on different columns not supported with skew in da

执行hive语句的时候报错:FAILED: SemanticException [Error 10022]: DISTINCT on different columns not supported with skew in data

报错原因:
当 hive.groupby.skewindata = true
执行下面语句就会报错

select count(distinct id),count(distinct x) from test;

当选项设定为 true,生成的查询计划会有两个MR Job。第一个MR Job中,Map的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,
并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个 MR Job 再根据第一个
MR JOB的数据结果按照Group By Key分布到Reduce(这个过程可以保证相同的Group By Key被分布到同一个Reduce中),最后完成最终的聚合操作。
注意:当启用时,能够解决数据倾斜的问题,但如果要在查询语句中对多个字段进行去重统计时会报错。

解决办法:
1、SELECT COUNT( DISTINCT id ) FROM TABLE_NAME WHERE …;
由于引入了DISTINCT,因此在Map阶段无法利用combine对输出结果消重,必须将id作为Key输出,在Reduce阶段只有一个reduce再对来自于不同Map Task,
相同Key的结果进行消重,计入最终统计值。
因为Hive在处理COUNT这种“全聚合(full aggregates)”计算时,它会忽略用户指定的Reduce Task数(mapred.reduce.tasks),而强制使用1个reduce。
2、改进写法:SELECT COUNT() FROM (SELECT DISTINCT id FROM TABLE_NAME WHERE … ) t;
改进后的写法会有两个MR作业,第一个MR作业选出全部的非重复id,可以通过增大Reduce的并发数,并发处理Map输出。第二个MR作业再对这些已消重的id进行计数。
由于id已经消重,因此COUNT(
)操作在Map阶段不需要输出原id数据,只输出一个合并后的计数即可。
实际运行时,Hive还对这两阶段的作业做了额外的优化。它将第二个MapReduce作业Map中的Count过程移到了第一个作业的Reduce阶段。
这样在第一阶Reduce就可以输出计数值,而不是消重的全部id。这一优化大幅地减少了第一个作业的Reduce输出IO以及第二个作业Map的输入数据量。

你可能感兴趣的:(FAILED: SemanticException [Error 10022]: DISTINCT on different columns not supported with skew in da)