Spark是否可以读取parquet文件的前一部分而不将其全部读到内存中?



假设我们有一个parquet文件(或其他任何文件)p,它有一些列和行。文件P有一个列a,只有0或1。此外,列A为0的行仅占该文件的1%。我们想读取列A为0的行

最简单的方法是全部读取并使用where将A过滤为1。这种方法花费a太多,因为我们实际上只需要文件P的1%,我们不能在读取P之前将P写入两个文件,其中a为0,a为1。如果你不把它读入内存,这看起来是不可能的,你怎么过滤它呢?

如果我们让文件p在写入磁盘之前按列A排序,我们可以在文件p的前一部分将A设为0。在这种情况下,Spark是否可以读取A为0的行?

这将取决于您正在谈论的文件格式,以及文件分区的方式。让我们讨论一下拼花文件:

分区列过滤

如果你的文件被这样写:

df.write.partitionBy("A").parquet(filename)

这是最好的情况。您的文件将以spark.read.parquet(filename).filter(col("A") === 0)只读取所需数据的方式写入。这是可能的原因是因为parquet文件对A列的每个值都有一个子目录。因此完全有可能不读取A == 1.

所在的目录。

对非分区列进行过滤

这是你使用的文件格式有影响的地方。在parquet文件的情况下,也有一些过滤被下推到读取文件。

拼花文件被分成行组。对于每个行组,parquet文件保留一些元数据(包括该行组的最小/最大值)。这允许跳过行组(假设您只想读取A == 0和最小值为1的值,您可以跳过整个行组)。

对于CSV文件,例如,第二个是不可能的。

相关内容

最新更新