本文摘自PHP中文网,作者不言,侵删。
本篇文章给大家带来的内容是关于Oracle表连接方式的优化方法(附示例) ,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
在Oracle数据库中,两个表之间的表连接方法有排序合并连接、嵌套循环连接、哈希连接和笛卡尔连接四种
1.排序合并连接(sort merge join)
排序合并连接是一种两表在做表连接时用排序(SORT)操作和合并(MERGE)操作来得到连接结果集的表连接方法
如果t1表和t2表在做表连接时使用的是排序合并连接,那么Oracle会依次执行如下步骤:
a.以目标SQL中指定的谓词条件访问t1表,然后对访问结果按照t1表的连接列排序,排好序后的结果集记为s1
b.以目标SQL中指定的谓词条件访问t2表,然后对访问结果按照t2表的连接列排序,排好序后的结果集记为s2
c.对s1和s2进行合并操作,从中取出匹配记录作为最终的结果集
排序合并连接的优缺点及适用场景:
a.通常情况下hash join的效果都比sort merge join要好,但是,如果行源已经被排过序,在执行sort merge join时不需要再排序,这时sort merge join的性能会优于hash join
b.通常情况下,只有在以下情况发生时,才会使用排序合并连接:
1)RBO模式
2)不等值连接(>,<,>=,<=)
3)哈希连接被禁用时(_HASH_JOIN_ENABLED=false)
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
SQL> select * from scott.emp t1,scott.emp t2 where t1.empno > t2.mgr;
89 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3950110903
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 62 | 4712 | 6 (17)| 00:00:01 |
| 1 | MERGE JOIN | | 62 | 4712 | 6 (17)| 00:00:01 |
| 2 | SORT JOIN | | 14 | 532 | 2 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID| EMP | 14 | 532 | 2 (0)| 00:00:01 |
| 4 | INDEX FULL SCAN | PK_EMP | 14 | | 1 (0)| 00:00:01 |
|* 5 | SORT JOIN | | 14 | 532 | 4 (25)| 00:00:01 |
| 6 | TABLE ACCESS FULL | EMP | 14 | 532 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access(INTERNAL_FUNCTION(
"T1"
.
"EMPNO"
)>INTERNAL_FUNCTION(
"T2"
.
"MGR"
))
filter(INTERNAL_FUNCTION(
"T1"
.
"EMPNO"
)>INTERNAL_FUNCTION(
"T2"
.
"MGR"
))
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
8 consistent gets
0 physical reads
0 redo size
6612 bytes sent via SQL*Net to client
575 bytes received via SQL*Net from client
7 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
89 rows processed
SQL>
2.嵌套循环连接(nested loops join)
嵌套循环连接是一种两表在做表连接时依靠两层嵌套循环(外层循环/内层循环)来得到连接结果集的表连接方法
如果t1表和t2表在做表连接时使用的是嵌套循环连接,那么Oracle会依次执行如下步骤:
a.首先,优化器会按照一定的规则来决定t1和t2谁是驱动表谁是被驱动表,驱动表用于外层循环,被驱动表用于内存循环。假设t1是驱动表
b.以目标SQL中指定的谓词条件访问驱动表t1,得到结果集s1
c.遍历s1,同时遍历被驱动表t2,即取出s1中的记录按照连接条件和被驱动表t2做匹配。最终将得到的结果集返回
嵌套循环连接的优缺点及适用场景:
a.能够实现快速响应,即可以第一时间先返回已经连接过且满足连接条件的记录,而不必等待所有的连接操作全部做完后才返回连接结果
b.适用于驱动表所对应的驱动结果集的记录数较少,同时在被驱动表的连接列上又存在唯一性索引(或者在被驱动表的连接列上存在选择性很好的非唯一性索引)的情况
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
SQL> select
* from scott.emp t1,scott.dept t2 where t1.deptno = t2.deptno;
SQL> select * from table(dbms_xplan.display_cursor(null,0,
'allstats,last'
));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID dcsf9m1rzzga5, child number 0
-------------------------------------
select
* from scott.emp
t1,scott.dept t2 where t1.deptno = t2.deptno
Plan hash value: 4192419542
-------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 14 |00:00:00.01 | 32 |
| 1 | NESTED LOOPS | | 1 | 14 | 14 |00:00:00.01 | 32 |
| 2 | TABLE ACCESS FULL| DEPT | 1 | 4 | 4 |00:00:00.01 | 7 |
|* 3 | TABLE ACCESS FULL| EMP | 4 | 4 | 14 |00:00:00.01 | 25 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
- filter(
"T1"
.
"DEPTNO"
=
"T2"
.
"DEPTNO"
)
rows selected.
SQL>
3.哈希连接(hash join)
哈希连接是一种两表在做表连接时依靠哈希运算来得到连接结果集的表连接方法,oracle 7.3之后引入
Hash join的工作方式是将一个表(通常是小一点的那个表)做hash运算并存储到hash列表中,从另一个表中抽取记录,做hash运算,到hash 列表中找到相应的值,做匹配
哈希连接只适用于CBO,也只能用于等值连接条件
哈希连接很适合于小表和大表做连接,特别是在小表的连接列的可选择性非常好的情况下,这时候哈希连接的执行时间就可以近似看作是和全表扫描那个大表所耗费的时间相当
哈希连接时,驱动结果集对应的Hash Table能够完全被容纳在内存中(PGA的工作区),此时的哈希连接的执行效率非常高
哈希连接的性能问题可以通过10104事件来诊断,相关说明如下:
Number of in-memory partitions (may have changed): Hash Partition Final number of hash buckets: Hash Bucket数量 Total buckets: Empty buckets: Non-empty buckets: Hash Bucket中空记录及非空记录的情况 Total number of rows: 驱动结果集的记录数 Maximum number of rows in a bucket: 包含记录数最多的Hash Bucket所含记录的数量 Disabled bitmap filtering: 是否启用位图过滤
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
SQL> select
* from scott.emp t1,scott.dept t2 where t1.deptno = t2.deptno;
SQL> select * from table(dbms_xplan.display_cursor(null,0,
'allstats,last'
));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 0j83q86ara5u2, child number 0
-------------------------------------
select
* from scott.emp
t1,scott.dept t2 where t1.deptno = t2.deptno
Plan hash value: 615168685
----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 14 |00:00:00.01 | 13 | | | |
|* 1 | HASH JOIN | | 1 | 14 | 14 |00:00:00.01 | 13 | 1321K| 1321K| 1070K (0)|
| 2 | TABLE ACCESS FULL| DEPT | 1 | 4 | 4 |00:00:00.01 | 6 | | | |
| 3 | TABLE ACCESS FULL| EMP | 1 | 14 | 14 |00:00:00.01 | 7 | | | |
----------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access(
"T1"
.
"DEPTNO"
=
"T2"
.
"DEPTNO"
)
21 rows selected.
SQL>
【相关推荐:SQL教程】
以上就是Oracle表连接方式的优化方法(附示例) 的详细内容,更多文章请关注木庄网络博客 !
相关阅读 >>
oracle 表空间查看sql使用情况
oracle 表空间数据库文件收缩案例解析
plsqldeveloper登录远程连接oracle 的操作
详解oracle 使用强制索引的方法与注意事项
oracle 10g 服务器端安装预备步骤(详细图文教程)
oracle 触发器的使用小结
详解oracle 中存储函数与存储过程
oracle 导出sql语句的结果集和保存执行的sql语句(深入分析)
oracle 常用功能集锦
如何在springboot项目中使用oracle 11g数据库
更多相关阅读请进入《oracle 》频道 >>
¥41.1元 机械工业出版社
本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。
转载请注明出处:木庄网络博客 » Oracle表连接方式的优化方法(附示例)