千家信息网

SWAP_JOIN_INPUTS Oracle Hint

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,swap_join_inputs是针对哈希连接的hint,它的含义是让优化器交换原哈希连接的驱动表和被驱动表的顺序,即在依然走哈希连接的情况下让原哈希连接的驱动表变被驱动表,让原哈希连接的被驱动表变为
千家信息网最后更新 2026年11月01日SWAP_JOIN_INPUTS Oracle Hint

swap_join_inputs是针对哈希连接的hint,它的含义是让优化器交换原哈希连接的驱动表和被驱动表的顺序,即在依然走哈希连接的情况下让原哈希连接的驱动表变被驱动表,让原哈希连接的被驱动表变为驱动表。

注意,在swap_join_inputs hint中指定的目标表应该是原哈希连接中的被驱动表,否则oracle会忽略该hint。

/*+ swap_join_inputs(原哈希连接的被驱动表) */

其使用范例如下:

select /*+ leading(dept) use_hash(emp) swap_join_intputs(emp) */ * from emp,dept whereemp.deptno=dept.deptno

测试案例:

SCOTT@ORA12C> create table t1 as select * from dba_objects where rownum<2;Table created.SCOTT@ORA12C> create table t2 as select * from dba_objects where rownum<12;Table created.SCOTT@ORA12C> create table t3 as select * from dba_objects where rownum<22;Table created.

收集统计信息:

SCOTT@ORA12C> exec dbms_stats.gather_table_stats(ownname => 'SCOTT',tabname => 'T1',estimate_percent => 100,cascade => true,method_opt => 'for all columns size 1',no_invalidate => false);PL/SQL procedure successfully completed.SCOTT@ORA12C> exec dbms_stats.gather_table_stats(ownname => 'SCOTT',tabname => 'T2',estimate_percent => 100,cascade => true,method_opt => 'for all columns size 1',no_invalidate => false);PL/SQL procedure successfully completed.SCOTT@ORA12C> exec dbms_stats.gather_table_stats(ownname => 'SCOTT',tabname => 'T3',estimate_percent => 100,cascade => true,method_opt => 'for all columns size 1',no_invalidate => false);PL/SQL procedure successfully completed.

3个表的记录如下:

SCOTT@ORA12C> select count(*) from t1; COUNT(*)-----------------11 row selected.SCOTT@ORA12C> select count(*) from t2; COUNT(*)-----------------       111 row selected.SCOTT@ORA12C> select count(*) from t3; COUNT(*)-----------------       211 row selected.

现在我们来让表T2和T3做哈希连接,由于T3表的记录数比T2表的记录数多,所以这里指定T3为哈希连接的被驱动表:

select /*+ ordered use_hash(t3) */ t2.object_name,t3.object_type  2  from t2,t3 where t2.object_id=t3.object_id;Execution Plan----------------------------------------------------------Plan hash value: 1730954469---------------------------------------------------------------------------| Id  | Operation   | Name | Rows  | Bytes | Cost (%CPU)| Time  |---------------------------------------------------------------------------|   0 | SELECT STATEMENT   |  |    11 |   220 |6   (0)| 00:00:01 ||*  1 |  HASH JOIN   |  |    11 |   220 |6   (0)| 00:00:01 ||   2 |   TABLE ACCESS FULL| T2   |    11 |   110 |3   (0)| 00:00:01 ||   3 |   TABLE ACCESS FULL| T3   |    21 |   210 |3   (0)| 00:00:01 |---------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - access("T2"."OBJECT_ID"="T3"."OBJECT_ID")

可以看到,上述SQL的执行计划现在走的是哈希连接,并且被驱动表示表T3.

如果我们想让哈希连接的被驱动表由T3变成T2,可以在上述sql加入swap_join_inputs hint:

select /*+ ordered use_hash(t3) swap_join_inputs(t3) */ t2.object_name,t3.object_type  2  from t2,t3 where t2.object_id=t3.object_id;Execution Plan----------------------------------------------------------Plan hash value: 1723280936---------------------------------------------------------------------------| Id  | Operation   | Name | Rows  | Bytes | Cost (%CPU)| Time  |---------------------------------------------------------------------------|   0 | SELECT STATEMENT   |  |    11 |   220 |6   (0)| 00:00:01 ||*  1 |  HASH JOIN   |  |    11 |   220 |6   (0)| 00:00:01 ||   2 |   TABLE ACCESS FULL| T3   |    21 |   210 |3   (0)| 00:00:01 ||   3 |   TABLE ACCESS FULL| T2   |    11 |   110 |3   (0)| 00:00:01 |---------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - access("T2"."OBJECT_ID"="T3"."OBJECT_ID")

用leading(t3) use_hash(t2)也可以同样达到目的:

select /*+ leading(t3) use_hash(t2) */ t2.object_name,t3.object_type  2  from t2,t3 where t2.object_id=t3.object_id;Execution Plan----------------------------------------------------------Plan hash value: 1723280936---------------------------------------------------------------------------| Id  | Operation   | Name | Rows  | Bytes | Cost (%CPU)| Time  |---------------------------------------------------------------------------|   0 | SELECT STATEMENT   |  |    11 |   220 |6   (0)| 00:00:01 ||*  1 |  HASH JOIN   |  |    11 |   220 |6   (0)| 00:00:01 ||   2 |   TABLE ACCESS FULL| T3   |    21 |   210 |3   (0)| 00:00:01 ||   3 |   TABLE ACCESS FULL| T2   |    11 |   110 |3   (0)| 00:00:01 |---------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - access("T2"."OBJECT_ID"="T3"."OBJECT_ID")

由此可见在两个表关联的时候,可以用其他hint代替swap_join_inputs来达到相同的目的:

那么多表关联呢:

select /*+ ordered use_hash(t3) */ t1.owner,t2.object_name,t3.object_type  2  from t2,t3,t1 where t2.object_id=t3.object_id and t1.object_type=t3.object_type;Execution Plan----------------------------------------------------------Plan hash value: 98820498----------------------------------------------------------------------------| Id  | Operation    | Name | Rows  | Bytes | Cost (%CPU)| Time   |----------------------------------------------------------------------------|   0 | SELECT STATEMENT    |   | 4 |   120 | 9   (0)| 00:00:01 ||*  1 |  HASH JOIN    |   | 4 |   120 | 9   (0)| 00:00:01 ||*  2 |   HASH JOIN    |   |11 |   220 | 6   (0)| 00:00:01 ||   3 |    TABLE ACCESS FULL| T2   |11 |   110 | 3   (0)| 00:00:01 ||   4 |    TABLE ACCESS FULL| T3   |21 |   210 | 3   (0)| 00:00:01 ||   5 |   TABLE ACCESS FULL | T1   | 1 |10 | 3   (0)| 00:00:01 |----------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - access("T1"."OBJECT_TYPE"="T3"."OBJECT_TYPE")   2 - access("T2"."OBJECT_ID"="T3"."OBJECT_ID"

可以看到,现在上述sql的执行计划是先由表T2和表T3做哈希连接,然后将他们做哈希连接的连接结果集再和表T1做一次哈希连接。

表T1的记录数为1,表T2的记录数为11,表T3的记录数为21,所以当表的T2和T3做哈希连接时,记录数多的表T3应该是被驱动表,这是因为我们在上述sql中使用了ordered hint和use_hash HINT指定表T3作为表T2和T3连接的时的被驱动表,所以oracle这里选择了表T2和T3做哈希连接,并且选择了表T3作为该哈希连接的被驱动表,这是没有问题的,现在问题在于表T1的记录数仅为1,所以当表T2和T3做哈希连接的结果再和表T1做哈希连接时,表T1应该是驱动表,而不是在上述执行计划里显示的那样作为第二个哈希连接的被驱动表。

使用下面HINT:

select /*+ ordered use_hash(t3) */ t1.owner,t2.object_name,t3.object_type  2  from t1,t2,t3 where t2.object_id=t3.object_id and t1.object_type=t3.object_type;Execution Plan----------------------------------------------------------Plan hash value: 38266800------------------------------------------------------------------------------| Id  | Operation      | Name | Rows  | Bytes | Cost (%CPU)| Time     |------------------------------------------------------------------------------|   0 | SELECT STATEMENT      |      |   4 | 120 |   9   (0)| 00:00:01 ||*  1 |  HASH JOIN      |      |   4 | 120 |   9   (0)| 00:00:01 ||   2 |   MERGE JOIN CARTESIAN|      |  11 | 220 |   6   (0)| 00:00:01 ||   3 |    TABLE ACCESS FULL  | T1   |   1 |  10 |   3   (0)| 00:00:01 ||   4 |    BUFFER SORT      |      |  11 | 110 |   3   (0)| 00:00:01 ||   5 |     TABLE ACCESS FULL | T2   |  11 | 110 |   3   (0)| 00:00:01 ||   6 |   TABLE ACCESS FULL   | T3   |  21 | 210 |   3   (0)| 00:00:01 |------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - access("T2"."OBJECT_ID"="T3"."OBJECT_ID" AND      "T1"."OBJECT_TYPE"="T3"."OBJECT_TYPE")
select /*+ leading(t1) use_hash(t3) */ t1.owner,t2.object_name,t3.object_type  2  from t1,t2,t3 where t2.object_id=t3.object_id and t1.object_type=t3.object_type;Execution Plan----------------------------------------------------------Plan hash value: 2308542799----------------------------------------------------------------------------| Id  | Operation    | Name | Rows  | Bytes | Cost (%CPU)| Time   |----------------------------------------------------------------------------|   0 | SELECT STATEMENT    |   | 7 |   210 | 9   (0)| 00:00:01 ||*  1 |  HASH JOIN    |   | 7 |   210 | 9   (0)| 00:00:01 ||*  2 |   HASH JOIN    |   | 7 |   140 | 6   (0)| 00:00:01 ||   3 |    TABLE ACCESS FULL| T1   | 1 |10 | 3   (0)| 00:00:01 ||   4 |    TABLE ACCESS FULL| T3   |21 |   210 | 3   (0)| 00:00:01 ||   5 |   TABLE ACCESS FULL | T2   |11 |   110 | 3   (0)| 00:00:01 |----------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - access("T2"."OBJECT_ID"="T3"."OBJECT_ID")   2 - access("T1"."OBJECT_TYPE"="T3"."OBJECT_TYPE")

加入以下hint,就解决:

SELECT /*+ ordered use_hash(t3) swap_join_inputs(t1) */ t1.owner, t2.object_name, t3.object_type  FROM t2, t3, t1 WHERE t2.object_id = t3.object_id  5     AND t1.object_type = t3.object_type;Execution Plan----------------------------------------------------------Plan hash value: 3071514789----------------------------------------------------------------------------| Id  | Operation    | Name | Rows  | Bytes | Cost (%CPU)| Time   |----------------------------------------------------------------------------|   0 | SELECT STATEMENT    |   | 4 |   120 | 9   (0)| 00:00:01 ||*  1 |  HASH JOIN    |   | 4 |   120 | 9   (0)| 00:00:01 ||   2 |   TABLE ACCESS FULL | T1   | 1 |10 | 3   (0)| 00:00:01 ||*  3 |   HASH JOIN    |   |11 |   220 | 6   (0)| 00:00:01 ||   4 |    TABLE ACCESS FULL| T2   |11 |   110 | 3   (0)| 00:00:01 ||   5 |    TABLE ACCESS FULL| T3   |21 |   210 | 3   (0)| 00:00:01 |----------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - access("T1"."OBJECT_TYPE"="T3"."OBJECT_TYPE")   3 - access("T2"."OBJECT_ID"="T3"."OBJECT_ID")


哈希 驱动 目的 结果 这是 问题 数多 关联 选择 相同 两个 中指 信息 含义 情况 时候 是在 案例 由此 由此可见 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 北京路客互联网科技有限公司 互联网科技有限公司经营范围 互联网的科技创新 互联网科技小贷 互联网与新科技 小马过河互联网科技 兼蜜互联网科技 玖二柒互联网科技公司待遇 互联网对科技的发展 岳阳华臻互联网科技有限公司 互联网科技商业 互联网与医疗科技 杭州披云加互联网科技有限公司 广州百诚互联网科技有限公司官网 富国互联网金融科技混合基金 北京互联网科技类企业分布 北京天晋互联网科技有限公司 互联网科技和医药行业 互联网的科技体现在哪里 小牛互联网科技有限公司地址 什么是科技互联网 广州为想互联网科技有限公司 艾特科技互联网 联恩商钥互联网科技有限公司 健康食品互联网创新科技园项目 上海科技产业互联网平台 互联网企业科技类企业如何做账 全球科技与互联网公司市值变化 绵阳真晨互联网科技有限公司 河南商务圈互联网科技有限公司
0