ITPub博客

首页 > 数据库 > 数据库开发技术 > Oracle SQL 性能调优:使用Hint固定执行计划1(Hash Join)

Oracle SQL 性能调优:使用Hint固定执行计划1(Hash Join)

原创 数据库开发技术 作者:lukeunique 时间:2021-04-13 08:08:00 0 删除 编辑

编者按:

本文作者系杨昱明,现就职于甲骨文公司,从事数据库方面的技术支持。希望能通过发表文章,把一些零散的知识再整理整理。个人主页:https://blog.csdn.net/weixin_50513167,经其本人授权发布。

【免责声明】本公众号文章仅代表个人观点,与任何公司无关。

Hash Join 是不使用索引等价结合时,最有效的结合方式,所以,使用的机会非常之多。


Hash Join 是在内存中作出 Hash Table 用来存放结合数据。通常,会先访问数据量少的表,之后再访问数据量多的表,这样能保证性能。


先访问的表叫做 Build表,第二个访问的表叫做 Probe表。那么假如 3个以上的表进行 Hash Join 时,各表之间的结合顺序,以及那个表作为 Build表,那个表作为 Probe表,如何来控制呢。


下面我们介绍一下相关的 Hint 来进行有效的控制。


LEADING Hint (指定 Hash Join 顺序)SWAP_JOIN_INPUTS Hint(指定 Build 表)NO_SWAP_JOIN_INPUTS Hint(指定 Probe 表)USE_HASH (指定使用 Hash Join)


下面用几个例子来做一下展示。


准备:


drop table t1 purge;drop table t2 purge;drop table t3 purge;create table t1(c1 number, c2 number);create table t2(c1 number, c2 number);create table t3(c1 number, c2 number);insert into t1 values (1,1);insert into t2 values (1,2);insert into t3 values (1,3);commit;



Case 1:

结合顺序是 A->B(Build 表)->C


SQL> select /*+ leading(a b c) use_hash(b c) swap_join_inputs(b) */ * from t1 a, t2 b, t3 c where a.c1=b.c1 and a.c1=c.c1;

C1 C2 C1 C2 C1 C2---------- ---------- ---------- ---------- ---------- ---------- 1 1 1 2 1 3

Execution Plan----------------------------------------------------------Plan hash value: 1184213596

----------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |----------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 78 | 9 (0)| 00:00:01 ||* 1 | HASH JOIN | | 1 | 78 | 9 (0)| 00:00:01 ||* 2 | HASH JOIN | | 1 | 52 | 6 (0)| 00:00:01 || 3 | TABLE ACCESS FULL| T2 | 1 | 26 | 3 (0)| 00:00:01 || 4 | TABLE ACCESS FULL| T1 | 1 | 26 | 3 (0)| 00:00:01 || 5 | TABLE ACCESS FULL | T3 | 1 | 26 | 3 (0)| 00:00:01 |----------------------------------------------------------------------------

Predicate Information (identified by operation id):---------------------------------------------------

1 - access("A"."C1"="C"."C1") 2 - access("A"."C1"="B"."C1")



Case 2:

结合顺序是 A->B(Build表)->C(Build表)


SQL> select /*+ leading(a b c) swap_join_inputs(b) swap_join_inputs(c) */ * from t1 a, t2 b, t3 c where a.c1=b.c1 and a.c1=c.c1;

C1 C2 C1 C2 C1 C2---------- ---------- ---------- ---------- ---------- ---------- 1 1 1 2 1 3

Execution Plan----------------------------------------------------------Plan hash value: 1487401159

----------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |----------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 78 | 9 (0)| 00:00:01 ||* 1 | HASH JOIN | | 1 | 78 | 9 (0)| 00:00:01 || 2 | TABLE ACCESS FULL | T3 | 1 | 26 | 3 (0)| 00:00:01 ||* 3 | HASH JOIN | | 1 | 52 | 6 (0)| 00:00:01 || 4 | TABLE ACCESS FULL| T2 | 1 | 26 | 3 (0)| 00:00:01 || 5 | TABLE ACCESS FULL| T1 | 1 | 26 | 3 (0)| 00:00:01 |----------------------------------------------------------------------------

Predicate Information (identified by operation id):---------------------------------------------------

1 - access("A"."C1"="C"."C1") 3 - access("A"."C1"="B"."C1")



Case 3:

结合顺序是 A->C(Build表)->B


SQL> select /*+ leading(a c b) USE_HASH(c b) swap_join_inputs(c) */ * from t1 a, t2 b, t3 c where a.c1=b.c1 and a.c1=c.c1;

C1 C2 C1 C2 C1 C2---------- ---------- ---------- ---------- ---------- ---------- 1 1 1 2 1 3



Execution Plan----------------------------------------------------------Plan hash value: 2467348796

----------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |----------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 78 | 9 (0)| 00:00:01 ||* 1 | HASH JOIN | | 1 | 78 | 9 (0)| 00:00:01 ||* 2 | HASH JOIN | | 1 | 52 | 6 (0)| 00:00:01 || 3 | TABLE ACCESS FULL| T3 | 1 | 26 | 3 (0)| 00:00:01 || 4 | TABLE ACCESS FULL| T1 | 1 | 26 | 3 (0)| 00:00:01 || 5 | TABLE ACCESS FULL | T2 | 1 | 26 | 3 (0)| 00:00:01 |----------------------------------------------------------------------------

Predicate Information (identified by operation id):---------------------------------------------------

1 - access("A"."C1"="B"."C1") 2 - access("A"."C1"="C"."C1")



另外,以上面的例子来说,可以用 C->B->A 的顺序进行 Hash Join 吗。不可以哈,因为 B表和 C表之间没有结合键,这样会产生笛卡尔积。


SQL> select /*+ leading(c b a) USE_HASH(c b) */ * from t1 a, t2 b, t3 c where a.c1=b.c1 and a.c1=c.c1;

C1 C2 C1 C2 C1 C2---------- ---------- ---------- ---------- ---------- ---------- 1 1 1 2 1 3



Execution Plan----------------------------------------------------------Plan hash value: 2210115829

------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | 78 | 9 (0)| 00:00:01 ||* 1 | HASH JOIN | | 1 | 78 | 9 (0)| 00:00:01 || 2 | MERGE JOIN CARTESIAN| | 1 | 52 | 6 (0)| 00:00:01 || 3 | TABLE ACCESS FULL | T3 | 1 | 26 | 3 (0)| 00:00:01 || 4 | BUFFER SORT | | 1 | 26 | 3 (0)| 00:00:01 || 5 | TABLE ACCESS FULL | T2 | 1 | 26 | 3 (0)| 00:00:01 || 6 | TABLE ACCESS FULL | T1 | 1 | 26 | 3 (0)| 00:00:01 |------------------------------------------------------------------------------

Predicate Information (identified by operation id):---------------------------------------------------

1 - access("A"."C1"="B"."C1" AND "A"."C1"="C"."C1")————————————————

后续文章更加精彩,欢迎关注本公众号或访问【阅读原文】。

——End——


专注于技术不限于技术!

用碎片化的时间,一点一滴地提高数据库技术和个人能力。

欢迎关注!


手把手系列(帮助个人技术成长):

SQL调优和诊断从哪入手?

获取SQL执行计划最基础的方法是啥?

一学就会的获取SQL执行计划和性能统计信息的方法

在线Oracle SQL学习环境--Live SQL

Oracle优化器架构变化和特定行为

获取历史执行计划:AWR/StatsPack SQL 报告

Oracle SQL 性能调优:使用SqlPatch固定执行计划

供收藏:Oracle固定SQL执行计划的方法总结


CBO 查询转换系列(了解Oracle优化器)

CBO 查询转换(1):子查询展开机能(Subquery Unnesting)

CBO 查询转换(2):反结合的NULL识别机能(null aware anti-join )

CBO 查询转换(3):结合谓词下推机能(Join Predicate Pushdown)

CBO 查询转换 (4):Group By 配置最优机能(Group By Placement)

CBO查询转换(5):星型转换(Star Transformation)

原文作者:SQL和数据库技术;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2017-07-21

  • 博文量
    107
  • 访问量
    63572