深入SQL执行计划之CBO查询转换(4):Group By 配置最优机能(Group By Placement)

2022-08-19 20:35:11 浏览数 (1)

编者按:

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

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

之前讲过的转换是当存在 View,子查询时,把子查询展开,或者把谓词下推给子查询。

那是不是说 CBO 只是盯着 View,或子查询来做工作呢,结论当然不是了。

比如2张表进行结合,并对其中一个表进行了 Group by 操作时,如果能先进行 Group by 的结果集再和另外的表进行结合的话,可能会有更好的效果。

于是乎,就有了Group By 配置最优机能(Group By Placement)。

Group By 配置最优机能(Group By Placement)

还是老样子,先看看最初没经过转换时的样子。

代码语言:javascript复制
drop table t1 purge;
drop table t2 purge;
create table t1(c1 number, c2 number not null);
create table t2(c1 number, c2 number not null);
insert into t1 values (1,1);
insert into t1 values (1,2);
insert into t1 values (2,2);
insert into t2 values (1,2);
commit;


SQL> select sum(t1.c2), t2.c2
from t1,t2
where t1.c1 = t2.c1
group by t2.c2;  2    3    4


SUM(T1.C2)         C2
---------- ----------
         3          2




Execution Plan
----------------------------------------------------------
Plan hash value: 51733071


----------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |     2 |   104 |     7  (15)| 00:00:01 |
|   1 |  HASH GROUP BY      |      |     2 |   104 |     7  (15)| 00:00:01 |
|*  2 |   HASH JOIN         |      |     2 |   104 |     6   (0)| 00:00:01 |
|   3 |    TABLE ACCESS FULL| T2   |     1 |    26 |     3   (0)| 00:00:01 |
|   4 |    TABLE ACCESS FULL| T1   |     3 |    78 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------


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


   2 - access("T1"."C1"="T2"."C1")

当然是先正常的 t1 t2 的结合,结合后的结果再进行 GROUP BY。

接下来,我们再看看 Group By 配置最优机能动作时的样子。

代码语言:javascript复制
SQL> select /*  PLACE_GROUP_BY((t1)) */ sum(t1.c2), t2.c2
from t1,t2
where t1.c1 = t2.c1
group by t2.c2;  2    3    4


SUM(T1.C2)         C2
---------- ----------
         3          2




Execution Plan
----------------------------------------------------------
Plan hash value: 2158485392


----------------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |     3 |   156 |     8  (25)| 00:00:01 |
|   1 |  HASH GROUP BY        |          |     3 |   156 |     8  (25)| 00:00:01 |
|*  2 |   HASH JOIN           |          |     3 |   156 |     7  (15)| 00:00:01 |
|   3 |    TABLE ACCESS FULL  | T2       |     1 |    26 |     3   (0)| 00:00:01 |
|   4 |    VIEW               | VW_GBC_1 |     3 |    78 |     4  (25)| 00:00:01 |
|   5 |     HASH GROUP BY     |          |     3 |    78 |     4  (25)| 00:00:01 |
|   6 |      TABLE ACCESS FULL| T1       |     3 |    78 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------------


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


   2 - access("ITEM_1"="T2"."C1")

t1 表被转换成 VW_GBC_1,这个 View 里先作 GROUP BY 处理,结果集再和 t2 进行结合。这个机能动作时的标识就是 VW_GBC_n 这个 View 名。

最后,想要关闭或者无效这个机能可以用以下方法:

代码语言:javascript复制
“_optimizer_group_by_placement”=FALSE。

OR

使用 NO_PLACE_GROUP_BY hint。

至此,CBO 的 SQL 自动转换这总结分享也就告一段落。希望能对各位同学有所帮助。如果能提出您的宝贵意见,那就非常荣幸了。

0 人点赞