昨天发现线上的HiveQuery:
1
|
select
*
from
db1.t1where dt
between
to_char(getdate(‘variables’,’-40’),’yyyymmdd’)
and
‘variables’
and
hour
=’xxx’(其中t1 partitioned bydt,
hour
)
|
不能进行partition prune导致执行效率非常的差,问题出现在哪里呢?
把To_Char函数的代码翻出来就一目了然了:
1
2
3
4
5
6
7
8
9
10
11
|
@UDFType
(deterministic=
false
)
@Description
(name=
"to_char"
,
value =
"_FUNC_(date, pattern) converts a string with yyyy-MM-dd HH:mm:sspattern "
+
"to a string with givenpattern.\n"
+
"_FUNC_(datetime, pattern) converts a string with yyyy-MM-dd pattern"
+
"to a string with givenpattern.\n"
+
"_FUNC_(number [,format]) convertsa number to a string\n"
,
extended =
"Example:\n"
+
" > SELECT to_char('2011-05-1110:00:12'.'yyyyMMdd') FROM src LIMIT 1;\n"
+
"20110511\n"
)
|
注意到这个函数是一个“非确定性”函数,Hive在做partition prune时考虑三点不进行过滤处理:
1.如果是逻辑函数的话,若所有的child节点都为null则忽略
2.非确定性函数忽略
3.其他情况,只要有child节点为null则忽略
而这里的to_char正是第二种情况,这里我们自己写了个确定性UDF来解决该问题
注:另外一个类似的Case HIVE-1173
本文转自MIKE老毕 51CTO博客,原文链接:http://blog.51cto.com/boylook/1365734,如需转载请自行联系原作者