谓词下推时使用sysdate函数导致分区过滤失效

  SQL报错
内容纲要

问题描述


客户描述,TDH6.0.2版本下,下面2个sql语句在使用时,SQL2执行只需要1s,而SQL1执行需要1900s+。

--SQL1:
> select * from jtw.v_td_gps_v1_bus2020 where select_dt =date_add((sysdate),-3) limit 1;
--SQL2:
> select * from jtw.v_td_gps_v1_bus2020 where select_dt='2020-11-01' limit 1;

排查思路


1. 检查DDL

DDL如下,范围分区分桶ORC事务表,select_dt就是它的分区键,每个分区下293个buckets。
SQL2能够正常查询到结果表示part10分区内确实存在数据,故SQL1应该是可以做到PartitionPruner的,猜测分区下推出现异常。

2. 排查hive-server2.log日志的task数

由于4040页面job信息刷新过快,已无法查看job details页面的task数目信息,故通过hive-server2.log日志进行排查。
排查发现map阶段起了多达2342个task,远远大于一个分区内的分桶数293。故证实未能实现分区下推。

注:
通过explain执行计划,可以简单的定位到在SelectOperator的expr中确实没能获取到实际的value,同样能够证实未能分区下推。

解决办法


自定义UDF,使用UDF函数替代sysdate

step0:获取依赖包

需要jar包hive-exec-0.12.0-transwarp-6.0.2.jar、hadoop-common-2.7.2-transwarp-6.0.2.jar,可以到inceptor容器的/usr/lib/inceptor/lib下获取

step1:自定义currentdate

import org.apache.hadoop.hive.common.type.HiveDate;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.hive.ql.udf.UDFType;
import org.apache.hadoop.hive.serde2.io.DateWritable;

@Description(name = "currentdate",
value = "FUNC -Return the current date",
extended = "Return the current date as format yyyy-MM-dd as default\n" +
"Example:\n" +
" > SELECT FUNC FROM src limit 1;\n" +
"2012-12-12"
)

@UDFType(deterministic = true)
public class UDFCurrentdate extends UDF {
DateWritable result = new DateWritable();

public UDFCurrentdate()

{ result.set(new HiveDate()); }
public DateWritable evaluate()

{ return result; }
}

step3:创建永久函数

1) udf.jar放到/usr/lib/inceptor/lib中,做镜像持久化(参考KB TDH安装Hotfix(换包)方法
2) beeline模式下,create permanent function currentdate as 'UDFCurrentdate';

step4: 使用语句进行测试,检查执行计划或者task数目是否降低

EXPLAIN 
SELECT * FROM people_range_partition WHERE  BORNDATE = date_add(sysdate,-5809);

修改为:

EXPLAIN 
SELECT * FROM people_range_partition WHERE  BORNDATE = date_add(currentdate(),-5809);

通过explain执行计划或者4040页面的task数目信息可以验证,分区下推成功!

这篇文章对您有帮助吗?

平均评分 5 / 5. 次数: 1

尚无评价,您可以第一个评哦!

非常抱歉,这篇文章对您没有帮助.

烦请您告诉我们您的建议与意见,以便我们改进,谢谢您。