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

2020-06-01 10:40:50 浏览数 (1)

作者:辉少

异常描述

  • 测试环境

1.RedHat7.2

2.CM和CDH版本为5.16.2

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

代码语言:javascript复制
select * from testdate;
SELECT * from testdate where Date(str2) == '2020-05-24';

异常重现

重新创建表复现该问题

代码语言:javascript复制
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');

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

代码语言:javascript复制
SELECT * from testdate2 where Date(str2) == '2020-05-24';
select * from testdate2;
SELECT * from testdate2 where str3 == '2020-05-25';

异常分析

关于以上问题,与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,因此受影响。

异常解决和总结

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

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

代码语言:javascript复制
set hive.optimize.constant.propagation = false; 
SELECT * from testdate2 where Date(str2) == '2020-05-24';

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

代码语言:javascript复制
SELECT * from testdate2 where substr(str2,1,10) = '2020-05-24';

参考文档:

代码语言:javascript复制
[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 人点赞