我有许多表(行数为1亿),都使用Parquet格式存储为外部Hive表。 Spark作业需要使用单个列将其中几个合并在一起,并且几乎没有过滤。连接列的唯一值比行数少大约2/3倍。
我可以看到join键正在发生混洗;而且我一直在尝试利用存储分区/分区来提高联接性能。我的想法是,如果可以使Spark意识到每个表都使用同一列进行存储,则它可以加载数据帧并加入它们,而不会进行改组。我曾经尝试过使用Hive铲斗,但是这种混洗并不会消失。 (从Spark的文档看来,至少从Spark 2.3.0开始,不支持Hive存储桶,我稍后会发现。)我可以使用Spark的存储桶功能来做到这一点吗?如果是,我是否必须禁用Hive支持并直接读取文件?还是我可以使用Spark的存储方案重写表一次,但仍然能够将它们读取为Hive表?
编辑:为了写出Hive存储桶表,我使用了类似的东西:
customerDF
.write
.option("path", "/some/path")
.mode("overwrite")
.format("parquet")
.bucketBy(200, "customer_key")
.sortBy("customer_key")
.saveAsTable("table_name")
写作部分似乎起作用。但是,从两个以这种方式编写的表中读取并连接它们并没有达到我的预期。也就是说,Spark再次将两个表重新划分为200个分区。
我现在没有执行Spark时段存储的代码,但是如果我发现了,它将进行更新。