我一直在使用partitionBy,但我不明白为什么要使用它。

我有这样的csv记录:

--------------------------- ---------
name | age | entranceDate | dropDate |
--------------------------------------
Tom  | 12  | 2019-10-01   | null     |
--------------------------------------
Mary | 15  | 2019-10-01   | null     |
--------------------------------------


如果我使用会发生什么:

String[] partitions =
new String[] {
  "name",
  "entranceDate"
};

df.write()
.partitionBy(partitions)
.mode(SaveMode.Append)
.parquet(parquetPath);


如果我在null列上分区怎么办:

String[] partitions =
new String[] {
  "name",
  "dropDate"
};

df.write()
.partitionBy(partitions)
.mode(SaveMode.Append)
.parquet(parquetPath);


谁能解释它是如何工作的?谢谢。

最佳答案

df.write.partitionBy的行为如下:


  
  对于数据框的每个分区,获取partitionBy参数中列的唯一值
  将每个唯一组合的数据写入不同的文件中
  


在上面的示例中,假设您的数据框有10个分区。让我们假设分区1-5具有名称和进入日期的5个唯一组合,分区6-10具有名称和进入日期的10个唯一组合。名称和进入日期的每种组合将被写入不同的文件。因此,每个分区1-5将被写入5个文件,而分区6-10将被划分为10个文件。写入操作生成的文件总数将为5 * 5 + 5 * 10 =75。partitionBy查看列组合的唯一值。从api的文档中:


  根据文件系统上给定的列对输出进行分区。如果
  指定后,输出将放置在类似于Hive的文件系统上
  分区方案。例如,当我们通过
  一年又一个月,目录布局如下所示:
  -年= 2016 /月= 01 /-年= 2016 /月= 02 /
  
  分区是最广泛使用的优化技术之一
  物理数据布局。它为跳过提供了粗粒度索引
  当查询对分区进行断言时,不必要的数据读取
  列。为了使分区正常工作,
  每列中的不同值通常应小于几十
  数千。
  
  这适用于所有基于文件的数据源(例如Parquet,
  JSON)从Spark 2.1.0开始。


partitionBy子句中的一列对所有行都具有相同的值,然后将根据partitionBy参数中其他列的值来拆分数据。

关于java - Spark:partitionBy(DataFrameWriter)实际如何工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58059462/

10-09 00:22