我遇到了一个问题,其中显然在Spark SQL中使用空表执行完全外连接会导致文件大小比仅仅从其他数据集中选择列而不进行连接。
基本上,我有两个数据集,其中一个非常大,另一个是空的。我经历了从大型数据集中选择几乎所有列,并将其全外部连接到空数据集。然后,我将结果数据集写入snappy-compressed镶木地板(我也尝试使用snappy压缩的orc)。或者,我只是从大数据集中选择相同的列,然后将结果数据集保存为如上所述的snappy压缩拼花(或orc)。文件大小完全不同,因为来自empty-dataset-join的文件几乎是简单选择文件的五倍。
我已经在许多不同的数据集上尝试了这一点,并得到了相同的结果。在查看数据时:
据我所知,使用空表进行连接实际上是没有意义的(我这样做是作为一些通用代码的一部分,它总是执行完全外连接,有时会遇到空数据集)。而且,我已经更新了我的代码,因此不再这样做了,所以问题就解决了。
不过,我想了解为什么/如何发生这种情况。所以我的问题是 - 为什么使用空数据集进行Spark SQL连接会导致更大的文件大小?和/或关于如何弄清楚生成的镶木地板文件如此之大的任何想法也会有所帮助。
答案 0 :(得分:1)
在遇到其他几种情况后,处理 way 数据中看似微小的差异会导致文件大小差异很大(对于看似完全相同的数据),我终于明白了这一点。
这里的关键是理解镶木地板(或orc)如何使用可能复杂的格式(如字典编码,游程编码等)对数据进行编码。这些格式利用数据冗余来缩小文件大小,即,如果您的数据包含许多类似的值,文件大小将小于许多不同的值。
在使用空数据集加入的情况下,重要的一点是当spark执行连接时,在连接列上进行分区。因此,即使使用空数据集,也可以更改数据分区的方式。
在我的情况下,使用空数据集连接将分区从在每个分区中将许多类似记录组合在一起的分区更改为在每个分区中分组了许多不同记录的分区。然后,当写出这些分区时,在每个文件中放入许多相似或不相似的记录。当分区具有相似的记录时,镶木地板的编码效率非常高,文件大小也很小;当分区多样化时,镶木地板的编码效率不高,文件大小也更大 - 即使整体数据完全相同。
如上所述,我们遇到了同样问题出现的其他几个实例 - 我们改变了处理的一个方面,并且会获得相同的输出数据,但文件大小可能会大四倍。有助于解决这个问题的一件事是使用parquet-tools
来查看低级文件统计信息。