如果我有一个用多级分区创建的表,即由两列(州、市)组成,如下所示:
state=CA,city=Anaheim
state=Texas,city=Houston
state=Texas,city=Dallas
state=Texas,city=Austin
state=CA,city=SanDiego
如果我运行这样的select查询:
select * from table_name where city=Houston
i、 在第二个分区列已经被使用的地方,它会扫描第二个分区列吗 city=Houston
分区 state=Texas
? 我很确定Hive是如何运作的,但我很想确认spark的行为。另外,如果在emr的spark中执行,行为会有什么不同吗?
2条答案
按热度按时间wfauudbj1#
如果您使用配置单元来存储表,那么它肯定能够对外部分区和内部分区进行分区修剪。hive单独保存关于表的分区信息的元数据。因此,当查询针对特定分区时,它能够进行优化。
你可以使用
explain select * from table_name where city ='Houston';
但是,如果您使用spark在嵌套结构中编写分区,那么我不太确定。如果查询需要遍历整个目录结构,那么当目录数量很大时,这将是非常昂贵的。iklwldmw2#
让我们从从从文件路径加载数据开始,而不是从元存储加载数据。在本例中,spark将首先执行递归文件列表,以发现嵌套分区文件夹及其内的文件。然后将分区文件夹定义为用于分区修剪的字段。因此,在您的情况下,当您对任何分区列进行筛选时,spark将只选择满足该 predicate 的分区。您可以使用
explain
方法。注意下面这个PartitionCount: 1
:将其与没有任何筛选器的查询计划进行比较,其中
PartitionCount: 5
:第二种情况是加载分区表。在这种情况下,分区是由配置单元管理的,这样可以节省昂贵的递归文件列表。在分区列上进行筛选时,spark将再次仅选择相关分区。注意
explain
计划如下: