在Spark SQL中使用目录进行分区剪枝

5

我有一些数据文件(本例中为json,但也可能是avro格式)存储在如下的目录结构中:

dataroot
+-- year=2015
    +-- month=06
        +-- day=01
            +-- data1.json
            +-- data2.json
            +-- data3.json
        +-- day=02
            +-- data1.json
            +-- data2.json
            +-- data3.json
    +-- month=07
        +-- day=20
            +-- data1.json
            +-- data2.json
            +-- data3.json
        +-- day=21
            +-- data1.json
            +-- data2.json
            +-- data3.json
        +-- day=22
            +-- data1.json
            +-- data2.json

使用spark-sql创建临时表:
CREATE TEMPORARY TABLE dataTable
USING org.apache.spark.sql.json
OPTIONS (
  path "dataroot/*"
)

查询表格可以正常工作,但是我目前还不能使用目录进行修剪。

有没有一种方法可以将目录结构注册为分区(不使用Hive),以避免在查询时扫描整个树?比如说,我想比较每个月的第一天的数据并只读取这些日期的目录。

使用Apache Drill,我可以在查询时使用目录作为谓词,例如dir0等。Spark SQL是否可以做类似的事情?


你能解决这个问题吗? - Vijay Muvva
不,当时我没有研究过这个具体案例,也没有深入了解过。 - Lundahl
2个回答

3

虽然Parquet文件读取确实支持类似Hive的分区发现,但根据我的经验,数据目录并没有作为分区加载。也就是说,当您查询分区键时,仍会扫描整个树(即没有剪枝 - 不是提问者想要的)。 - Jack Leow
@jack,它使用分区来跳过并且不读取目录(仅适用于parquet文件)。 - Arnon Rotem-Gal-Oz
自从那条评论以来,我实际上学到了更多。因此,分区可用时可以获得优化,但仅在使用DataFrames API时才能获得。如果转换为RDD(甚至在使用Datasets API时,据我所知),它将始终读取所有目录,即使它不必这样做。换句话说,您所说的是准确的,但仅在使用DataFrame API时才是如此。 - Jack Leow
现在Spark中的文本文件表是否支持分区剪枝? - Harikrishnan Ck

2
使用EXPLAIN查看物理计划,以便了解将扫描哪个文件夹。
此外,在创建表时可以描述分区,以便Spark可以使用它。
我不确定Spark 1.6是否正确使用分区剪枝,将spark.sql.hive.convertMetastoreParquet设置为false时,我可以看到它,但将其设置为true(默认值),我可以看到Spark将扫描所有分区(但这并不影响性能)。

每个问题都是不同的,但在不同的问题设置中,切换开关有所帮助。在我看来,这总是值得一试的。 - Marcel Flygare

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接