问题描述
这可能是一个愚蠢的问题, 但是,在镶木地板文件中手动指定分区列与加载然后过滤它们之间有什么区别吗?
例如:
我有一个被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
已经存在了一段时间,使您的生活更加轻松。例如。分区修剪和实木复合地板统计信息的使用,例如最小/最大。请参阅2017年的https://db-blog.web.cern.ch/blog/luca-canali/2017-06-diving-spark-and-parquet-workloads-example,它也适用于pyspark。
并非所有内容都会被下推,但其他可以下推的运算符为“ ,> =”,如2017年的链接所示。您可以使用.explain
来检查优化器如何应用或不应用谓词下推。