我使用的是Spark SQL 2.2.0。
在执行查询时,如:
spark.sql("select COL1, min(STRING_COL2)
from TB1 group by COL1").explain()Spark将使用sort aggregate,因为STRING_COL2是一个字符串列。在大多数情况下,基于排序的聚合比基于散列的聚合要昂贵得多。
在GROUP BY子句中指定字符串列不会强制基于排序的聚合。
如果你用sort_array(collect_set(STRING_COL1))[0]代替min(STRING_COL1),Spark将使用ObjectHashAggregation,这比SortAggregate要好得多(在我的例子中快了两倍)。
然而,与仅仅比较两个值相比,收集一组不同的值、对其进行排序并最终获取第一个值需要更多的内存和更多的CPU资源(正如MIN应该做的那样)。此外,如果聚合了多个条目,则ObjectHashAggregation将回退到SortAggregate。
如何在内存消耗不断增加的情况下避免繁重的排序?为什么HashAggregate不支持字符串列的最小值和最大值?什么时候会被支持?
谢谢。
发布于 2021-01-19 15:22:17
您可以先配置spark.sql.execution.useObjectHashAggregateExec = true,
它从spark 2.2.0开始使用,如果它不工作,你可以在更高版本的spark中尝试。
并检查string_C1是否太长;
发布于 2021-07-18 17:44:18
默认为基于散列的聚合,但当GROUP BY中的键太多,超过基于散列的聚合的缓冲区大小时,它可能会回退到基于排序的聚合。
参见this blog。
https://stackoverflow.com/questions/47741297
复制相似问题