执行计划】Oracle 11gR2使用Full outer Joins执行计划完成全外连接查询
1.创建实验表并初始化实验数据
sys@ora11g> select * from v$version;
BANNER
------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
conn sec/sec
create table a (a number(1),b number(1),c number(1));
create table b (a number(1),d number(1),e number(1));
insert into a values(1,1,1);
insert into a values(2,2,2);
insert into a values(3,3,3);
insert into b values(1,4,4);
insert into b values(2,5,5);
insert into b values(4,6,6);
commit;
2.两种实现全外连接查询的方法
1)第一种方法:使用两次外连接结合union的方法
select * from a,b where a.a=b.a(+)
union
select * from a,b where a.a(+)=b.a;
2)第二种方法:使用全外连接标准写法
select * from a full outer join b on a.a = b.a;
3.比较两种执行方法的执行计划
1)反复执行第一种方法得到稳定的执行计划
sec@ora11g> select * from a,b where a.a=b.a(+)
2 union
3 select * from a,b where a.a(+)=b.a;
A B C A D E
---------- ---------- ---------- ---------- ---------- ----------
1 1 1 1 4 4
2 2 2 2 5 5
3 3 3
4 6 6
Execution Plan
----------------------------------------------------------
Plan hash value: 891669117
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6 | 468 | 15 (60)| 00:00:01 |
| 1 | SORT UNIQUE | | 6 | 468 | 15 (60)| 00:00:01 |
| 2 | UNION-ALL | | | | | |
|* 3 | HASH JOIN OUTER | | 3 | 234 | 7 (15)| 00:00:01 |
| 4 | TABLE ACCESS FULL| A | 3 | 117 | 3 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL| B | 3 | 117 | 3 (0)| 00:00:01 |
|* 6 | HASH JOIN OUTER | | 3 | 234 | 7 (15)| 00:00:01 |
| 7 | TABLE ACCESS FULL| B | 3 | 117 | 3 (0)| 00:00:01 |
| 8 | TABLE ACCESS FULL| A | 3 | 117 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("A"."A"="B"."A"(+))
6 - access("A"."A"(+)="B"."A")
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
28 consistent gets
0 physical reads
0 redo size
792 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
4 rows processed
2)反复执行第二种方法得到稳定的执行计划
sec@ora11g> select * from a full outer join b on a.a = b.a;
A B C A D E
---------- ---------- ---------- ---------- ---------- ----------
1 1 1 1 4 4
2 2 2 2 5 5
4 6 6
3 3 3
Execution Plan
----------------------------------------------------------
Plan hash value: 3456740935
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 234 | 7 (15)| 00:00:01 |
| 1 | VIEW | VW_FOJ_0 | 3 | 234 | 7 (15)| 00:00:01 |
|* 2 | HASH JOIN FULL OUTER| | 3 | 234 | 7 (15)| 00:00:01 |
| 3 | TABLE ACCESS FULL | A | 3 | 117 | 3 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | B | 3 | 117 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("A"."A"="B"."A")
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
15 consistent gets
0 physical reads
0 redo size
792 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
4 rows processed
3)执行计划对比结果
第一种外连接结合union方法对表进行了两次扫描,而全外连接方法引入了HASH JOIN FULL OUTER执行计划仅需对表进行一次扫描便得到了查询结果。从consistent gets上也很直观,全外连接写法(28)比union方法(15)的consistent gets少了一半。
4.小结
Oracle对全外连接的支持越来越好,从最初Oracle不支持全外连接的SQL写法,到支持SQL的特定写法,同时从执行计划上也在逐渐优化中。
sys@ora11g> select * from v$version;
BANNER
------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
conn sec/sec
create table a (a number(1),b number(1),c number(1));
create table b (a number(1),d number(1),e number(1));
insert into a values(1,1,1);
insert into a values(2,2,2);
insert into a values(3,3,3);
insert into b values(1,4,4);
insert into b values(2,5,5);
insert into b values(4,6,6);
commit;
2.两种实现全外连接查询的方法
1)第一种方法:使用两次外连接结合union的方法
select * from a,b where a.a=b.a(+)
union
select * from a,b where a.a(+)=b.a;
2)第二种方法:使用全外连接标准写法
select * from a full outer join b on a.a = b.a;
3.比较两种执行方法的执行计划
1)反复执行第一种方法得到稳定的执行计划
sec@ora11g> select * from a,b where a.a=b.a(+)
2 union
3 select * from a,b where a.a(+)=b.a;
A B C A D E
---------- ---------- ---------- ---------- ---------- ----------
1 1 1 1 4 4
2 2 2 2 5 5
3 3 3
4 6 6
Execution Plan
----------------------------------------------------------
Plan hash value: 891669117
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6 | 468 | 15 (60)| 00:00:01 |
| 1 | SORT UNIQUE | | 6 | 468 | 15 (60)| 00:00:01 |
| 2 | UNION-ALL | | | | | |
|* 3 | HASH JOIN OUTER | | 3 | 234 | 7 (15)| 00:00:01 |
| 4 | TABLE ACCESS FULL| A | 3 | 117 | 3 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL| B | 3 | 117 | 3 (0)| 00:00:01 |
|* 6 | HASH JOIN OUTER | | 3 | 234 | 7 (15)| 00:00:01 |
| 7 | TABLE ACCESS FULL| B | 3 | 117 | 3 (0)| 00:00:01 |
| 8 | TABLE ACCESS FULL| A | 3 | 117 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("A"."A"="B"."A"(+))
6 - access("A"."A"(+)="B"."A")
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
28 consistent gets
0 physical reads
0 redo size
792 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
4 rows processed
2)反复执行第二种方法得到稳定的执行计划
sec@ora11g> select * from a full outer join b on a.a = b.a;
A B C A D E
---------- ---------- ---------- ---------- ---------- ----------
1 1 1 1 4 4
2 2 2 2 5 5
4 6 6
3 3 3
Execution Plan
----------------------------------------------------------
Plan hash value: 3456740935
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 234 | 7 (15)| 00:00:01 |
| 1 | VIEW | VW_FOJ_0 | 3 | 234 | 7 (15)| 00:00:01 |
|* 2 | HASH JOIN FULL OUTER| | 3 | 234 | 7 (15)| 00:00:01 |
| 3 | TABLE ACCESS FULL | A | 3 | 117 | 3 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | B | 3 | 117 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("A"."A"="B"."A")
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
15 consistent gets
0 physical reads
0 redo size
792 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
4 rows processed
3)执行计划对比结果
第一种外连接结合union方法对表进行了两次扫描,而全外连接方法引入了HASH JOIN FULL OUTER执行计划仅需对表进行一次扫描便得到了查询结果。从consistent gets上也很直观,全外连接写法(28)比union方法(15)的consistent gets少了一半。
4.小结
Oracle对全外连接的支持越来越好,从最初Oracle不支持全外连接的SQL写法,到支持SQL的特定写法,同时从执行计划上也在逐渐优化中。
本文来自博客园,作者:Iven_lin,转载请注明原文链接:https://www.cnblogs.com/ivenlin/p/18110711
分类:
Oracle
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了