为什么查询性能与Spark SQL中的嵌套列不同?

Emr*_*lak 5 parquet apache-spark-sql

我使用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)
|    |-- count5: integer (nullable = false)
|-- global: struct (nullable = true)
|    |-- count1: integer (nullable = false)
|    |-- count2: integer (nullable = false)
|    |-- count3: integer (nullable = false)
|    |-- count4: integer (nullable = false)
|    |-- count5: integer (nullable = false)
Run Code Online (Sandbox Code Playgroud)

我也可以将相同的数据转换为更扁平的模式,如下所示:

root
|-- stateLevelCount1: integer (nullable = false)
|-- stateLevelCount2: integer (nullable = false)
|-- stateLevelCount3: integer (nullable = false)
|-- stateLevelCount4: integer (nullable = false)
|-- stateLevelCount5: integer (nullable = false)
|-- countryLevelCount1: integer (nullable = false)
|-- countryLevelCount2: integer (nullable = false)
|-- countryLevelCount3: integer (nullable = false)
|-- countryLevelCount4: integer (nullable = false)
|-- countryLevelCount5: integer (nullable = false)
|-- globalCount1: integer (nullable = false)
|-- globalCount2: integer (nullable = false)
|-- globalCount3: integer (nullable = false)
|-- globalCount4: integer (nullable = false)
|-- globalCount5: integer (nullable = false)
Run Code Online (Sandbox Code Playgroud)

现在,当我对像global.count1这样的列上的第一个数据集运行查询时,它比在第二个数据集中查询globalCount1要花费更长的时间.相反,将第一个数据集写入Parquet比写第二个数据集要短很多.我知道由于Parquet,我的数据以柱状方式存储,但我认为所有嵌套列都将单独存储在一起.例如,在第一个数据集中,似乎整个"全局"列存储在一起,而不是"global.count1","global.count2"等值存储在一起.这是预期的行为吗?

Tag*_*gar 0

有趣的。“这比查询花费的时间要长得多..”您能分享一下需要多长时间吗?谢谢。

查看代码https://github.com/Parquet/parquet-mr/blob/master/parquet-column/src/main/java/parquet/io/RecordReaderImplementation.java#L248似乎从结构中读取可能有一些高架。尽管只看 Parquet 代码,它不应该“更长”。

我认为更大的问题是 Spark 如何在这种情况下下推谓词。例如,在这种情况下它可能无法使用布隆过滤器。您能否分享一下您在两种情况和时间下查询数据的方式。Spark、Parquet、Hadoop 等哪些版本?

Parquet-1.5 存在问题https://issues.apache.org/jira/browse/PARQUET-61,在某些情况下可能会导致 4-5 倍的速度减慢。