Databricks中读取全部Parquet分区是否比读取全量Parquet更慢?
在Databricks上用PySpark读取全量数据时,按Hotel分区的main_bookings_partitioned.parquet通常不会比未分区的main_bookings.parquet慢很多,最多是略慢,核心原因集中在分区带来的额外开销上,具体如下:
分区元数据扫描开销
分区表会为每个Hotel值生成独立的目录(比如Hotel=HotelA/、Hotel=HotelB/),Spark读取时需要先遍历所有分区目录,加载每个目录下的文件元数据(包括文件大小、位置、分区键值等)。如果Hotel的基数很大(比如上万个不同酒店),这一步的目录扫描和元数据收集会比未分区表(仅扫描根目录下的文件)多消耗一些时间。小文件带来的任务调度开销
分区后每个分区内的文件通常更小,如果分区数量多,总文件数会远超过未分区表。Spark处理大量小文件时,需要拆分出更多的任务(每个小文件对应至少一个任务),Driver的任务调度、Executor的任务启动与切换都会产生额外开销。比如未分区表是10个1GB的文件,对应10个任务;分区后变成1000个10MB的文件,对应1000个任务,调度成本会明显上升。分区优势无法发挥
分区的核心价值是数据裁剪——当查询过滤Hotel字段时,Spark可以直接跳过无关分区的文件,大幅减少IO。但读取全量数据时,这个优势完全用不上,反而要承担分区带来的额外成本。不过Databricks的内置优化(比如分区元数据缓存、Parquet文件索引)会抵消部分开销,所以不会出现“慢很多”的情况。
如果你的Hotel基数不大(比如几百个以内),这种性能差异几乎可以忽略;但如果基数极大,可能会看到明显的初始延迟,但整体数据读取的IO效率和未分区表接近,因为Parquet的列式存储和压缩特性在两种场景下是一致的。
内容的提问来源于stack exchange,提问作者Albert Cuspinera Permanyer ES

