A1:你对createOrReplaceTempView的评价是对的。这将在当前 Spark 会话中惰性进行评估。换句话说,如果您终止 Spark 会话而不访问它,则数据将永远不会传输到 temp1。
A2:让我们通过使用您的代码的示例来检查案例。首先让我们保存您的数据:
df.write.mode("overwrite").option("header", "true")
.partitionBy("Year", "Month")
.format("csv")
.save("/tmp/partition_test1/")
然后加载它:
val df1 = spark.read.option("header", "true")
.csv("/tmp/partition_test1/")
.where($"Year" === 2019 && $"Month" === 5)
执行df1.explain会返回:
== Physical Plan ==
*(1) FileScan csv [Day#328,SalesAmount#329,StoreNumber#330,Year#331,Month#332] Batched: false, Format: CSV, Location: InMemoryFileIndex[file:/tmp/partition_test1], PartitionCount: 0, Partition
Filters: [isnotnull(Year#331), isnotnull(Month#332), (Year#331 = 2019), (Month#332 = 5)], PushedFilters: [], ReadSchema: struct<Day:string,SalesAmount:string,StoreNumber:string>
您可以看到PushedFilters: [] 数组是空的,尽管PartitionFilters[] 不是,这表明Spark 能够对分区应用过滤,因此修剪不满足where 语句的分区。
如果我们将 Spark 查询稍微更改为:
df1.where($"StoreNumber" === 1 && $"Year" === 2011 && $"Month" === 11).explain
== Physical Plan ==
*(1) Project [Day#462, SalesAmount#463, StoreNumber#464, Year#465, Month#466]
+- *(1) Filter (isnotnull(StoreNumber#464) && (cast(StoreNumber#464 as int) = 1))
+- *(1) FileScan csv [Day#462,SalesAmount#463,StoreNumber#464,Year#465,Month#466] Batched: false, Format: CSV, Location: InMemoryFileIndex[file:/tmp/partition_test1], PartitionCount: 1, Par
titionFilters: [isnotnull(Month#466), isnotnull(Year#465), (Year#465 = 2011), (Month#466 = 11)], PushedFilters: [IsNotNull(StoreNumber)], ReadSchema: struct<Day:string,SalesAmount:string,Store
Number:string>
现在PartitionFilters 和PushedFilters 都将发生,以最大限度地减少 Spark 工作负载。如您所见,Spark 首先通过 PartitionFilters 识别现有分区,然后应用谓词下推,从而利用这两个过滤器。
同样适用于 parquet 文件,最大的区别在于 parquet 将利用谓词下推过滤器甚至更多地将它们与其内部基于列的系统(如您已经提到的)相结合,该系统保留数据的指标和统计信息。所以与 CSV 文件的区别在于,对于 CSV,谓词下推将在 Spark 读取/扫描 CSV 文件时发生,不满足谓词下推条件的记录除外。对于 parquet,谓词下推过滤器将传播到 parquet 内部系统,从而导致更大的数据修剪。
在您的情况下,从 createOrReplaceTempView 加载数据不会有所不同,执行计划将保持不变。
一些有用的链接:
https://spark.apache.org/docs/latest/sql-data-sources-parquet.html
https://www.waitingforcode.com/apache-spark-sql/predicate-pushdown-spark-sql/read
https://jaceklaskowski.gitbooks.io/mastering-spark-sql/spark-sql-SparkStrategy-FileSourceStrategy.html