我有以下(简化的)架构:
root
|-- event: struct (nullable = true)
| |-- spent: struct (nullable = true)
| | |-- amount: decimal(34,3) (nullable = true)
| | |-- currency: string (nullable = true)
| |
| | ... ~ 20 other struct fields on "event" level
Run Code Online (Sandbox Code Playgroud)
我正在尝试对嵌套字段求和
spark.sql("select sum(event.spent.amount) from event")
Run Code Online (Sandbox Code Playgroud)
根据火花指标,我从磁盘读取 18 GB,需要 2.5 分钟。
但是,当我选择顶级字段时:
spark.sql("select sum(amount) from event")
Run Code Online (Sandbox Code Playgroud)
我在 4 秒内只读取了 2GB。
从物理计划中我可以看到,在嵌套结构的情况下,所有字段的整个事件结构都是从 parquet 中读取的,这是一种浪费。
Parquet 格式应该能够从嵌套结构中提供所需的列,而无需全部读取(这是列式存储的重点)。有没有办法在 Spark 中有效地做到这一点?
我使用Spark SQL以Parquet格式编写一些数据,其结果模式如下所示:
root
|-- stateLevel: struct (nullable = true)
| |-- count1: integer (nullable = false)
| |-- count2: integer (nullable = false)
| |-- count3: integer (nullable = false)
| |-- count4: integer (nullable = false)
| |-- count5: integer (nullable = false)
|-- countryLevel: struct (nullable = true)
| |-- count1: integer (nullable = false)
| |-- count2: integer (nullable = false)
| |-- count3: integer (nullable = false)
| |-- count4: integer (nullable = false)
| |-- …Run Code Online (Sandbox Code Playgroud)