Spark cần nạp phân vùng metdata đầu tiên trong trình điều khiển để biết phân vùng có tồn tại hay không. Spark sẽ truy vấn thư mục để tìm các phân vùng hiện có để biết nó có thể cắt phân vùng hay không trong quá trình quét dữ liệu.
Tôi đã thử nghiệm điều này trên Spark 2.0 và bạn có thể thấy trong thông báo tường trình.
16/10/14 17:23:37 TRACE ListingFileCatalog: Listing s3a://mybucket/reddit_year on driver
16/10/14 17:23:37 TRACE ListingFileCatalog: Listing s3a://mybucket/reddit_year/year=2007 on driver
Điều này không có nghĩa là chúng tôi đang quét các tệp trong từng phân đoạn, nhưng Spark sẽ lưu trữ vị trí của phân đoạn cho các truy vấn trong tương lai trên bảng.
Bạn có thể xem các bản ghi mà nó thực sự là đi qua trong các bộ lọc phân vùng để prune dữ liệu:
16/10/14 17:23:48 TRACE ListingFileCatalog: Partition spec: PartitionSpec(StructType(StructField(year,IntegerType,true)),ArrayBuffer(PartitionDirectory([2012],s3a://mybucket/reddit_year/year=2012), PartitionDirectory([2010],s3a://mybucket/reddit_year/year=2010), ...PartitionDirectory([2015],s3a://mybucket/reddit_year/year=2015), PartitionDirectory([2011],s3a://mybucket/reddit_year/year=2011)))
16/10/14 17:23:48 INFO ListingFileCatalog: Selected 1 partitions out of 9, pruned 88.88888888888889% partitions.
Bạn có thể thấy điều này trong kế hoạch hợp lý nếu bạn chạy một explain(True)
trên truy vấn của bạn: spark.sql("select created_utc, score, name from reddit where year = '2014'").explain(True)
này sẽ cho bạn kế hoạch và bạn có thể thấy rằng nó được lọc ở dưới cùng của kế hoạch:
+- *BatchedScan parquet [created_utc#58,name#65,score#69L,year#74] Format: ParquetFormat, InputPaths: s3a://mybucket/reddit_year, PartitionFilters: [isnotnull(year#74), (cast(year#74 as double) = 2014.0)], PushedFilters: [], ReadSchema: struct<created_utc:string,name:string,score:bigint>
Tôi đã gặp sự cố tương tự và tôi đã giải quyết nó bằng \ '\' - cố gắng sử dụng một cái gì đó như 'sqlContext.sql (" chọn tên, giá từ products_parquet_151 trong đó \ 'month \' = '2014-12' ")' – VladoDemcak
không giải quyết được. Vấn đề là tia lửa phát ra một cuộc gọi danh mục mà không cần đẩy bộ lọc xuống lớp HDFS thấp hơn –