手动选择镶木地板分区与在 pyspark 中过滤它们

Hand selecting parquet partitions vs filtering them in pyspark

这可能是个愚蠢的问题, 但是在 parquet 文件中手动指定分区列与加载它然后过滤它们之间有什么区别吗?

例如: 我有一个按 DATE 分区的镶木地板文件。如果我想要最后 10 天,我通常可以执行以下操作:(假设今天是 2020-10-26)

df=spark.read.parquet("s3://bucket/path/file.parquet")\
.filter(col('DATE')>'2020-10-15')

或者我可以使用 S3 文件系统仅加载 spark 数据框中所需的分区,如下所示:

inpath="s3://bucket/path/file.parquet/"
datepath=s3fs.S3FileSystem.ls(inpath)
dates=[]
for a in range(len(datepath)-10, len(datepath)):
    path="s3://" + datepath[a] + "/"
    dates=append(path)
df=spark.read.option("basePath", inpath).parquet(*dates)

在第二种方法(在我的想法中)中以精心制作的方式进行操作的原因是,我不必加载内存中包含所有日期的整个镶木地板文件,然后过滤它们。 我想知道我的假设是否正确。

请指教。 谢谢

两者都可以,但 Spark predicate push-down 已经存在了一段时间,让您的生活更轻松。例如。分区修剪和使用 parquet 统计信息,例如 min/max。请参阅 2017 年的 https://db-blog.web.cern.ch/blog/luca-canali/2017-06-diving-spark-and-parquet-workloads-example,它也适用于 pyspark。

并非所有内容都可以被下推,但其他可以被下推的运算符是“<、<=、>、>=”,如 2017 年的 link 所示。您可以使用 .explain 检查优化器如何应用或不应用谓词 push-down.