作者:辉少
异常描述
- 测试环境
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](https://i-blog.csdnimg.cn/blog_migrate/4234d0012f430489383937fa8b6c52a3.jpeg)
异常重现
重新创建表复现该问题
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](https://i-blog.csdnimg.cn/blog_migrate/a984e80572268b03d96f74ce070e7de2.jpeg)
分别使用带Date 函数条件、不带条件 、以及其他条件查看,确认的确存在该问题
SELECT * from testdate2 where Date(str2) == '2020-05-24';select * from testdate2;SELECT * from testdate2 where str3 == '2020-05-25';
![69720bc59811b64eacf1d8f89ab5ec22.png](https://i-blog.csdnimg.cn/blog_migrate/51ab3cccebb4ba5fa9165c5a29c2c70a.jpeg)
![e8536ae224b80e7b91a0a230df2622b7.png](https://i-blog.csdnimg.cn/blog_migrate/119abfad04bff923b6a3aeb80884bf58.jpeg)
异常分析
关于以上问题,与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](https://i-blog.csdnimg.cn/blog_migrate/91dd6c31641c2e2079c4336f2b7688f5.jpeg)
异常解决和总结
对于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](https://i-blog.csdnimg.cn/blog_migrate/cb667e2f30fa9c68210d70d9d433d576.jpeg)
2.使用其他函数代替Date 函数,比如substr(str2,1,10) = '2020-05-24'
SELECT * from testdate2 where substr(str2,1,10) = '2020-05-24';
![f671bbbeca565bf805b9d236f75d1b8f.png](https://i-blog.csdnimg.cn/blog_migrate/7750fb5fe8529b6cefd7c627a837b0d1.jpeg)
参考文档:
[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