ORACLE表连接
ORACLE表连接
一、什么是表连接?
表的连接是指在一个SQL语句中通过表与表之间的关联,从一个或多个表检索出相关的数据。
二、ORACLE的优化器使用的表连接有哪些?
1.嵌套循环连接(NESTED LOOP JOIN)
2.群集连接(CLUSTER JOIN)
3.排序合并连接(SORT MERGE JOIN)
4.笛卡尔连接(CARTESIAL JOIN)
5.哈希连接(HASH JOIN)
6.索引连接(INDEX JOIN)
三、各种表连接的内部处理流程
1.嵌套循环连接(NESTED LOOP JOIN)
1)ORACLE优化器根据基于规则RBO或基于成本CBO的原则,选择两个表中的一个作为驱动表,并指定其为外部表;
2)ORACLE优化器再将另外一个表指定为内部表;
3)ORACLE从外部表中读取第一行,然后和内部表中的数据逐一进行对比,所有匹配的记录放在结果集中;
4)ORACLE读取外部表中的第二行,再和内部表中的数据逐一进行对比,所有匹配的记录添加到结果集中;
5)重复上述步骤,直到外部表中的所有记录全部处理完;
6)最后产生满足要求的结果集。
2.群集连接(CLUSTER JOIN)
群集连接实际上是嵌套循环连接的一种特例。
1)ORACLE优化器根据基于规则RBO或基于成本CBO的原则,选择两个表中的一个作为驱动表,并指定其为外部表;
2)ORACLE优化器再将另外一个表指定为内部表;
3)ORACLE从外部表中读取第一行,然后在内部表中使用CLUSTER索引查找能够匹配到的纪录,所有匹配的记录放在结果集中;
4)ORACLE读取外部表中的第二行,再在内部表中使用CLUSTER索引查找能够匹配到的纪录,所有匹配的记录添加到结果集中;
5)重复上述步骤,直到外部表中的所有记录全部处理完;
6)最后产生满足要求的结果集。
注:群集连接的效率极高,因为两个参加连接的行源表实际上处于同一个物理块上。但是,群集连接也有其限制,没有群集的两个表不可能用群集连接。
3.排序合并连接(SORT MERGE JOIN)
1) 优化器判断第一个行源表是否已经排序,如果已经排序,则到第3步,否则到第2步;
2) 第一个源表排序;
3) 优化器判断第二个行源表是否已经排序,如果已经排序,则到第5步,否则到第4步;
4) 第二个源表排序;
5) 已经排过序的两个源表进行合并操作,并生成最终的结果集。
注:在缺乏数据的选择性或者可用的索引时,或者两个行源表都过于庞大(所选的数据超过表记录数的5%)时,排序合并连接将比嵌套循环连更加高效。排列合并连接需要比较大的临时内存块,以用于排序,
这将导致在临时表空间占用更多的内存和磁盘I/O。
4.笛卡尔连接(CARTESIAL JOIN)
笛卡尔连接是指在sql语句中没有写出表连接的条件,优化器把第一个表的每一条记录和第二个表的所有纪录相连接。如果第一个表的纪录数为m, 第二个表的纪录数为m,则会产生m*n条纪录数。
5.哈希连接(HASH JOIN)
当内存能够提供足够的空间时,哈希(HASH)连接是ORACLE优化器通常的选择。哈希连接中,优化器根据统计信息,首先选择两个表中的小表,在内存中建立这张表的基于连接键的哈希表;优化器再扫描表
连接中的大表,将大表中的数据与哈希表进行比较,如果有相关联的数据,则将数据添加到结果集中。当表连接中的小表能够完全cache到可用内存的时候,哈希连接的效果最佳。哈希连接的成本只是两
个表从硬盘读入到内存的成本。但是,如果哈希表过大而不能全部cache到可用内存时,优化器将会把哈希表分成多个分区,再将分区逐一cache到内存中。当表的分区超过了可用内存时,分区的部分数
据就会临时地写到磁盘上的临时表空间上。因此,分区的数据写磁盘时,比较大的区间(EXTENT)会提高I/O性能。ORACLE推荐的临时表空间的区间是1MB。临时表空间的区间大小由UNIFORM SIZE指定。
当哈希表构建完成后,进行下面的处理:
1)第二个大表进行扫描
2)如果大表不能完全cache到可用内存的时候,大表同样会分成很多分区
3)大表的第一个分区cache到内存
4)对大表第一个分区的数据进行扫描,并与哈希表进行比较,如果有匹配的纪录,添加到结果集里面
5)与第一个分区一样,其它的分区也类似处理。
6)所有的分区处理完后,ORACLE对产生的结果集进行归并,汇总,产生最终的结果。
注:当哈希表过大或可用内存有限,哈希表不能完全CACHE到内存。随着满足连接条件的结果集的增加,可用内存会随之下降,这时已经CACHE到内存的数据可能会重新写回到硬盘去。如果出现这种情况
,系统的性能就会下降。当连接的两个表是用等值连接并且表的数据量比较大时,优化器才可能采用哈希连接。哈希连接是基于CBO的。只有在数据库初始化参数HASH_JOIN_ENABLED设为True,并且为参数
PGA_AGGREGATE_TARGET设置了一个足够大的值的时候,ORACLE才会使用哈希边连接。
6.索引连接(INDEX JOIN)
如果一组已存在的索引包含查询条件所需要的信息,那么优化器可能会选择索引连接,通过索引查找结果集。
四、几种常见表连接的比较
类别
嵌套循环连接 |
排序合并连接 |
哈希连接 |
HINT |
USE_NL |
USE_MERGE |
USE_HASH |
条件 |
任何连接 |
不等价连接 |
等价连接 |
资源 |
CPU、磁盘I/O |
内存、临时表空间 |
内存、临时表空间 |
特点 |
当有高选择性索引或进行限制性搜索时效率较高,能够快速返回第一次的搜索结果。 |
当缺乏索引或者索引条件模糊时,排序合并连接比嵌套循环有效 |
当缺乏索引或者索引条件模式时,哈希连接比嵌套循环有效。通常比排序合并连接快。 |
缺点 |
当索引丢失或者查询条件限制不够时,效率很低;当表的记录数多时,效率低 |
所有的表都需要排序。它为最优化的吞吐量而设计,并且在结果没有全部找到前不返回数据。 |
为建立哈希表,需要大量内存。第一次的结果返回较慢 |
五、连接应用举例
SQL> create table user_info(user_id char(32),user_name varchar2(10));
SQL> create table dev_info(dev_no char(32),user_id char(32),dev_type varchar2(10));
SQL> set autotrace traceonly explain;
1.嵌套循环连接(NESTED LOOP JOIN)
SQL> select /*+ use_nl(a b) */ a.user_name, b.dev_no
from user_info a, dev_info b
where a.user_id = b.user_id;
Execution Plan
----------------------
Plan hash value: 1772694585
--------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------