hive 时间函数_0777-5.16.2-Hive中使用Date函数用于条件查询结果异常分析

作者:辉少

异常描述

  • 测试环境

1.RedHat7.2

2.CM和CDH版本为5.16.2

在CDH5.16.2 中使用Hive时 ,当Hive 的查询where条件中使用Date函数后,函数中的列的值会在返回结果中被改变,导致结果不正确。具体表现为使用Date 函数当查询条件后导致string 格式的日期丢失了时间部分,只有日期。展示如下:

select * from testdate;SELECT * from testdate where Date(str2) == '2020-05-24';
0cfe2bc2de085e63ec1295db33dbf8e6.png

异常重现

重新创建表复现该问题

create table testdate2 (str1 string , str2 string ,str3 string, str4 string);insert into table testdate2 values ("日期测试1",'2020-05-24 19:50:32','2020-05-24','testdate');insert into table testdate2 values ("日期测试2",'2020-05-24 20:20:32','2020-05-25','testdate2');
8d62bed6538133dfe8b2af333a4abd32.png

分别使用带Date 函数条件、不带条件 、以及其他条件查看,确认的确存在该问题

SELECT * from testdate2 where Date(str2) == '2020-05-24';select * from testdate2;SELECT * from testdate2 where str3 == '2020-05-25';
69720bc59811b64eacf1d8f89ab5ec22.png
e8536ae224b80e7b91a0a230df2622b7.png

异常分析

关于以上问题,与Hive的一个已知BUG HIVE-22513[1]有关,主要是由于Hive对列条件过滤操作中的持续传播从而导致错误的结果。Hive 自0.14.0开始,加入了一项CBO (Cost based Optimizer),来对HQL执行计划进行优化,这个功能通过”hive.cbo.enable”来开启。Hive 1.1.0 之后,该功能默认开启,而CDH5.16.2 中Hive 版本1.1.0,因此受影响。

cf051225a55320cfea694fa7b292749a.png

异常解决和总结

对于Date函数持续传播从而导致错误的结果基于上述分析,提供以下2种解决办法

1.单个查询中临时关闭CBO,在Hive 1.1.0 可以通过set hive.optimize.constant.propagation = false; 来临时关闭单个查询,缺点是可能会影响query的性能。从参考文档[2][3]中可以看出,使用constant.propagation会在一定条件下在query进入执行阶段前预先计算部分值,所以对query影响具体是因query不同而不同的。

set hive.optimize.constant.propagation = false; SELECT * from testdate2 where Date(str2) == '2020-05-24';
1af6945e8891836435675ce8637f805f.png

2.使用其他函数代替Date 函数,比如substr(str2,1,10) = '2020-05-24'

SELECT * from testdate2 where substr(str2,1,10) = '2020-05-24';
f671bbbeca565bf805b9d236f75d1b8f.png

参考文档:

[1] https://issues.apache.org/jira/browse/HIVE-22513[2] https://en.wikipedia.org/wiki/Constant_folding#Constant_propagation[3] https://issues.apache.org/jira/browse/HIVE-5771
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
```scala // 将 DataFrame 的数据写入到 Hudi 表 mysqlDF.write.format("org.apache.hudi") .options(Map( TABLE_TYPE_OPT_KEY -> "MERGE_ON_READ", // Hudi 表的类型,这里是“MERGE_ON_READ” RECORDKEY_FIELD_OPT_KEY -> "id", // 记录键,这里是“id” PRECOMBINE_FIELD_OPT_KEY -> "timestamp", // 预合并字段,这里是“timestamp” PARTITIONPATH_FIELD_OPT_KEY -> "date", // 分区路径键,这里是“date” KEYGENERATOR_CLASS_OPT_KEY -> "org.apache.hudi.keygen.NonpartitionedKeyGenerator", // 键生成器的类,这里是“org.apache.hudi.keygen.NonpartitionedKeyGenerator” HIVE_SYNC_ENABLED_OPT_KEY -> "true", // 是否启用 Hive 元数据同步,这里是“true” HIVE_DATABASE_OPT_KEY -> "default", // Hive 数据库的名称,这里是“default” HIVE_TABLE_OPT_KEY -> "hudi_table", // Hive 表的名称,这里是“hudi_table” HIVE_PARTITION_FIELDS_OPT_KEY -> "date", // Hive 分区字段,这里是“dateHIVE_PARTITION_EXTRACTOR_CLASS_OPT_KEY -> "org.apache.hudi.hive.NonPartitionedExtractor", // Hive 分区提取器的类,这里是“org.apache.hudi.hive.NonPartitionedExtractor” HIVE_STYLE_PARTITIONING_OPT_KEY -> "true", // 是否启用 Hive 样式的分区,这里是“true” HIVE_ASSUME_DATE_PARTITION_OPT_KEY -> "false" // 是否启用日期分区,这里是“false” )) .mode("append") // 写入模式,这里是“append”,即添加新数据 .save("/path/to/hudi_table") // 保存路径,这里是 Hudi 表的路径 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值