分区发现
表分区是在系统中(如Hive)常见的一种优化方法。在一个分区的表中,数据通常是存储在不同的目录下的,列被解码成每个分区目录的路径。Parquet数据源现在可以自动发现和推断分区信息。例如,我们可以使用以下的目录结构,存储前面所有使用的填充的数据到一个已分区的表中,额外的两列gender和country被作为分区列。
path
└── to
└── table
├── gender=male
│ ├── ...
│ │
│ ├── country=US
│ │ └── data.parquet
│ ├── country=CN
│ │ └── data.parquet
│ └── ...
└── gender=female
├── ...
│
├── country=US
│ └── data.parquet
├── country=CN
│ └── data.parquet
└── ...
通过传递path/to/table
给SQLContext.read.parquet
或SQLContext.read.load
,Spark SQL将处自动地提取路径的分区信息。现在返回的DataFrame的schema变成了:
root
|-- name: string (nullable = true)
|-- age: long (nullable = true)
|-- gender: string (nullable = true)
|-- country: string (nullable = true)
注意到,分区列的数据类型都是自动推断出来的。当前,支持数字数据类型和字符串类型。有时候,用户可能不想自动推断分区列的数据类型。对于这种情况,自动类型推断能够通过spark.sql.sources.partitionColumnTypeInference.enabled
来配置,这个值默认是true
。当类型推断没有启用时,string类型将被用于分区列。
从Spark 1.6.0开始,默认情况下,分区发现只能找给出路径的分区。对于以上例子,如果用户传递path/to/table/gender=male
给SQLContext.read.parquet
或SQLContext.read.load
gender将不会被考虑作为一个分区列。如果用户需要指定分区发现应该开始的基路径,他们可以设置basePath在数据源选项中。例如,当数据的路径为path/to/table/gender=male
且用户设置basePath
为path/to/table/
时,gender
将会是一个分区列。