hive使用exists时把join条件放在where条件里,导致第三个join开始的条件都丢失

3 篇文章 1 订阅

测试模拟数据准备:

test_table1
cust_no,name
60001,lisa
60002,tina
60003,kylin
60004,jeny
60005,john
60006,jamse

test_table2
cust_no,acct_type
60001,1
60001,1
60001,2
60002,1
60003,2
60003,3

test_table3
cust_no
60001
60002
60003
60004
60005
60007

test_table4
cust_no,cust_level
60001,1
60002,2
60003,3
60004,4
60005,5

测试环境:

由于是小表把mapJoin关闭

set hive.auto.convert.join=false;

测试sql

select t1.cust_no as cust_no,t2.cust_no as custNO,t1.name,t4.cust_level from tmp.test_table1 t1
left join tmp.test_table2 t2 on t1.cust_no=t2.cust_no
and t2.acct_type='1'
left join tmp.test_table4 t4 on t1.cust_no=t4.cust_no
where t2.cust_no is null and t4.cust_level not in ('4','5') and exists (select 1 from tmp.test_table3 t3 where t1.cust_no=t3.cust_no);

通过查看执行计划,发现 t4.cust_level not in ('4','5')条件丢失,导致查询出来的数据不正确

错误结果

60003 NULL kylin
60004 NULL jeny
60005 NULL john

正确的目标结果:

60003 NULL kylin

通过分析hive的参数,发现是谓词下推导致的丢失结果hive.optimize.ppd,这个参数默认是true,false情况数据量太大。跟踪代码发现生成的RS(ReduceSink)里少t2表。在谓词下推时会使用这个表别名去作为key查找这个谓词是否需要下推,key存在就去下推谓词,否则谓词不生效。

跟踪代码发现当exists时,只获取了右连接别名的第一个表,其他表都不会去遍历获取

错误代码在语义分析类SemanticAnalyzer的genSQJoinTree方法(备注hive-1.1.0版本)的7900行实现里。

错误代码段

String[] leftChildAliases = leftTree.getLeftAliases();
String leftAliases[] = new String[leftChildAliases.length + 1];
for (int i = 0; i < leftChildAliases.length; i++) {
leftAliases[i] = leftChildAliases[i];
}
leftAliases[leftChildAliases.length] = leftTree.getRightAliases()[0];
joinTree.setLeftAliases(leftAliases);

修改代码段:

if ( !joinTree.getNoSemiJoin() ) {
String[] leftChildAliases = leftTree.getLeftAliases();
String[] rightChildAliases = leftTree.getRightAliases();
String leftAliases[] = new String[leftChildAliases.length + rightChildAliases.length];
for (int i = 0; i < leftChildAliases.length; i++) {
leftAliases[i] = leftChildAliases[i];
}
for (int i = 0; i < rightChildAliases.length; i++) {
leftAliases[leftChildAliases.length + i] = rightChildAliases[i];
}
joinTree.setLeftAliases(leftAliases);
} else {
String[] leftChildAliases = leftTree.getLeftAliases();
String leftAliases[] = new String[leftChildAliases.length + 1];
for (int i = 0; i < leftChildAliases.length; i++) {
leftAliases[i] = leftChildAliases[i];
}
leftAliases[leftChildAliases.length] = leftTree.getRightAliases()[0];
joinTree.setLeftAliases(leftAliases); 
}

增加当是exists时,去遍历右连接表的所有表别名,把它存放起来

在hive JRIA提的bug是HIVE-21452

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zxl333

原创不容易

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值