sparkSQL可以指定分区字段为varchar类型吗

举报
留在夏天的海洋 发表于 2021/09/01 11:46:03 2021/09/01
【摘要】     首先我们可以查到,Hive从0.12.0版本就支持varchar类型作为列的类型了,但是sparkSQL可以指定分区字段为varchar类型吗?我们可以先实验一下。首先我们尝试创建一个分区字段为varchar类型的表,执行语句如下:CREATE TABLE test0901222(LIST_RES_ID STRING, age Int) PARTITIONED BY (DATA_DA...


    首先我们可以查到,Hive从0.12.0版本就支持varchar类型作为列的类型了,但是sparkSQL可以指定分区字段为varchar类型吗?我们可以先实验一下。首先我们尝试创建一个分区字段为varchar类型的表,执行语句如下:CREATE TABLE test0901222(LIST_RES_ID STRING, age Int) PARTITIONED BY (DATA_DATE VARCHAR(8)),然后发现是可以创建成功的,如下图所示:

111.jpg

然后尝试在这个表上以分区字段作为条件进行查询,执行语句:select * from test0818222 where DATA_DATE = '20210428'。执行后发现有很奇怪的报错,如下图所示:

222.jpg


   这是怎么回事呢?查看spark内核代码找到相关代码如下图所示:

333.jpg

问题就出在getPartitionsByFilter这个方法中。可以看到这里是用反射的方法获取filter的信息的,但是hive的官方文档明确指出,使用反射的方法获取varchar类型信息是不支持的,如下图所示:

444.png

那么我们没有办法支持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

555.jpg

可以看到如果spark内核改为依赖自己内部的参数如shouldFallback就不会出现上述的问题了。这样spark可以自己指定filter执行失败后是否回退或者直接抛出异常。

 

根据以上分析,我们可以总结结论如下:

  • sparkSQL不是一定不可以指定分区字段为varchar类型的,根据不同的版本不同的配置参数理论上分析有可能是可行的。
  • 由于varchar不支持反射获取所以getPartitionsByFilter中一定会执行报错,如果走回退的分支的话会显著的降低性能。所以从性能的角度来分析即使可行也不推荐指定varchar类型作为分区字段,推荐可以根据不同的场景选择String、Int等类型作为分区字段。

 

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。