此hint仅针对hash_join有效,强行交换驱动关系;目标表为 原hash连接的被驱动表,适合的场景:
1.多表的hash内连接(大于2个以上)
2.多表的hash外连接(大于等于2个以上)
场景1:
--2个表的内连接
select /*+ leading(d) use_hash(e) swap_join_inputs(e)*/ * from dept d,emp e
where d.deptno=e.deptno;
可以看到,首先d作为驱动表,e被驱动,然后强行反转e;
此情况,没必要用swap_join_inputs,用leading就可以指定了;
场景2
--2个表的外连接
select /*+ leading(e) use_hash(d) */ * from dept d,emp e
where d.deptno=e.deptno(+);
这里看到,leading失效了,那么可以使用swap_join_inputs(e)强行反转;
select /*+ leading(e) use_hash(d) swap_join_inputs(e)*/ * from dept d,emp e
where d.deptno=e.deptno(+);
场景3:
多个表的内连接下交换顺序
drop table t1;
drop table t2;
drop table t3;
create table t1
as
select * from dba_objects where rownum<2;
create table t2
as
select * from dba_objects where rownum<12;
create table t3
as
select * from dba_objects where rownum<22;
select /*+ ordered use_hash(t3)*/
t1.owner, t2.data_object_id
from t2, t3, t1
where t2.object_id = t3.object_id
and t1.object_id = t3.object_id;
或者
select /*+ leading(t2) use_hash(t3)*/
t1.owner, t2.data_object_id
from t2, t3, t1
where t2.object_id = t3.object_id
and t1.object_id = t3.object_id;
如果想反过来,让T1作为第一个驱动表,怎么实现?
–方式1:leading 不对
select /+ leading(t1) use_hash(t2 t3)/
t1.owner, t2.data_object_id
from t2, t3, t1
where t2.object_id = t3.object_id
and t1.object_id = t3.object_id;
这里t2,t3虽然都作为了被驱动,但是顺序不对;
–方式2swap_join_inputs
select /+ leading(t2) use_hash(t3) swap_join_inputs(t1)/
t1.owner, t2.data_object_id
from t2, t3, t1
where t2.object_id = t3.object_id
and t1.object_id = t3.object_id;
这就对了