怎样才能归类
1385
2022-05-30
首先我们可以查到,Hive从0.12.0版本就支持varchar类型作为列的类型了,但是sparkSQL可以指定分区字段为varchar类型吗?我们可以先实验一下。首先我们尝试创建一个分区字段为varchar类型的表,执行语句如下:CREATE TABLE test0901222(LIST_RES_ID STRING, age Int) PARTITIONED BY (DATA_DATE VARCHAR(8)),然后发现是可以创建成功的,如下图所示:
然后尝试在这个表上以分区字段作为条件进行查询,执行语句:select * from test0818222 where DATA_DATE = '20210428'。执行后发现有很奇怪的报错,如下图所示:
这是怎么回事呢?查看spark内核代码找到相关代码如下图所示:
问题就出在getPartitionsByFilter这个方法中。可以看到这里是用反射的方法获取filter的信息的,但是hive的官方文档明确指出,使用反射的方法获取varchar类型信息是不支持的,如下图所示:
那么我们没有办法支持varchar作为分区字段了吗,也不是的。让我们回到上面的spark内核代码,可以发现如果tryDirectSql如果为false时,getPartitionsByFilter会跳过filter然后回退到返回所有的分区(当然这样会显著的降低性能)。那么tryDirectSql又是什么呢,tryDirectSql是hive的配置,配置项为hive.metastore.try.direct.sql,主要控制Metastore 是否应该尝试使用SQL直接查询存储路径。
但是spark内核是否回退到不使用filter的行为依赖hive的参数配置是不合理的,如果我们希望把hive.metastore.try.direct.sql设置为true的同时(这样设置在某些场景下可以提高性能)又希望getPartitionsByFilter执行失败会回退到不使用filter就无法实现了。搜索后发现其实针对这个问题开源社区是有修改的,MR链接:https://github.com/apache/spark/pull/33382。
可以看到如果spark内核改为依赖自己内部的参数如shouldFallback就不会出现上述的问题了。这样spark可以自己指定filter执行失败后是否回退或者直接抛出异常。
根据以上分析,我们可以总结结论如下:
sparkSQL不是一定不可以指定分区字段为varchar类型的,根据不同的版本不同的配置参数理论上分析有可能是可行的。
由于varchar不支持反射获取所以getPartitionsByFilter中一定会执行报错,如果走回退的分支的话会显著的降低性能。所以从性能的角度来分析即使可行也不推荐指定varchar类型作为分区字段,推荐可以根据不同的场景选择String、Int等类型作为分区字段。
spark
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。