出自:http://www.itpub.net/thread-207865-1-1.htmlhtml
通常常见的Oracle数据库链接有3种:算法
Nested Loop,Merge,Hash Join数据库
1.嵌套循环联接NL(Neeted Loop)
嵌套循环联接也称为嵌套迭代,它将一个联接输入用做外部输入表(显示为图形执行计划中的顶端输入),将另外一个联接输入用做内部(底端)输入表。外部循环逐行消耗外部输入表。oracle
内部循环为每一个外部行执行,在内部输入表中搜索匹配行。最简单的状况是,搜索时扫描整个表或索引;这称为单纯嵌套循环联接。异步
若是搜索时使用索引,则称为索引嵌套循环联接。函数
若是将索引生成为查询计划的一部分(并在查询完成后当即将索引破坏),则称为临时索引嵌套循环联接。查询优化器考虑全部这些不一样形式。oop
若是外部输入很小而内部输入很大且预先建立了索引,则嵌套循环联接尤为有效。优化
在许多小事务中(如那些只影响较小的一组行的事务),索引嵌套循环联接远比合并联接和哈希联接优越。但在大查询中,嵌套循环联接一般不是最佳选择。.net
总而言之,nested loop适合于关联2个表结果集小的,并且关联字段上面存在索引的数据。线程
2.合并联接(Merge)
合并联接要求两个输入都在合并列上排序,而合并列由联接谓词的等效 (WHERE) 子句定义。查询优化器通常扫描索引(若是在适当的一组列上存在一个索引),或在合并联接的下面放一个排序运算符。在不多的状况下,虽然可能有多个等效子句,但只用其中一些可用的等效子句得到合并列。
因为每一个输入都已排序,Merge Join 运算符将获取每一个输入中的行并将其进行比较。例如,对于内联接操做,若是行相等则返回。若是行不相等,则废弃值较小的行并从该输入中得到另外一行。这一过程将重复进行,直处处理完全部的行为止。
合并联接操做能够是常规操做,也能够是多对多操做。多对多合并联接使用临时表存储行。若是每一个输入中有重复值,则在处理其中一个输入中的每一个重复项时,另外一个输入必须重绕到重复项的开始位置。
若是存在驻留谓词,全部知足合并谓词的行都将对该驻留谓词取值,而后只返回那些知足该驻留谓词的行。
合并联接自己的速度很快,但若是须要排序操做,选择合并联接就会很是费时。然而,若是数据量很大且可以从现有 B 树索引中得到预排序的所需数据,则合并联接一般是最快的可用联接算法。
3.哈希联接(Hash Join)
哈希联接有两种输入:生成输入和探测输入。查询优化器指派这些角色,使两个输入中较小的那个做为生成输入。
哈希联接可用于许多类型的集合匹配操做:内联接,左向外联接、右向外联接和完整外联接,左向半联接和右向半联接、交集、联合和差分。并且,哈希联接的变化形式可以进行重复项删除和分组操做(如 SUM(salary) GROUP BY department)。这些修改对生成和探测角色只使用一个输入。
与合并联接类似,只有当联接谓词中至少有一个等效 (WHERE) 子句时才能使用哈希联接。然而,联接通常用于重组合由主键和外键之间的等效谓词表达的关系,所以大多数联接至少有一个等效子句。用等效谓词表达的列集合称为哈希键,由于这些列有助于哈希函数。还能够有附加的谓词,而且能够将这些谓词取值为驻留谓词以与哈希值比较分开。哈希键能够是表达式,只要能从单个行中的列对其进行排它计算。在分组操做中,按列表分组的列是哈希键。在交集等集合操做中以及删除复制项时,哈希键由全部列组成。
关于哈希链接的补充:
内存中的哈希联接
哈希联接先扫描或计算整个生成输入,而后在内存中生成哈希表。根据为哈希键计算出的哈希值,将每行插入哈希存储桶。若是整个生成输入比可用内存少,则能够将全部行都插入哈希表中。生成阶段后接着是探测阶段。一次一行地对整个探测输入进行扫描或计算,并为每一个探测行计算哈希键的值,扫描相应的哈希存储桶并生成匹配项。
Grace 哈希联接
若是生成输入不适合内存,哈希联接将分步进行。每一步都包括生成阶段和探测阶段。首先,消耗整个生成和探测输入并(使用哈希键上的哈希函数)将其分区为多个文件。这类文件的数目称为分区输出端。经过使用哈希键上的哈希函数,能够保证任意两个联接记录必在相同的文件对中。所以,联接两个大输入的任务简化为相同任务的多个较小的实例。而后将哈希联接应用于每对分区文件。
递归哈希联接
若是生成输入很是大,以致于标准外部合并排序的输入须要多个合并级别,则须要多个分区步骤和多个分区级别。若是只有某些分区较大,则只需对这些分区使用附加的分区步骤。为使全部的分区步骤尽量快,将使用大的异步 I/O 操做以便单个线程就能使多个磁盘驱动器繁忙工做。
表链接用法介绍:
1.何时使用NL
必须有一个table拥有index;
只用一个table有index时,选择没有index的table做为驱动表;
当两个table都有index时,选择结果集较小的table做为驱动表 (CBO),RBO会选from的最后一个表作驱动表;
适用于有index的链接,两个有大小差别的结果集,数据量较小。
2.Merge Join
合并列要求排序;
在不使用index的状况下使用MR join:
在链接table的字段上不存在可用的index;
查询将返回两个table中大部分的数据块;
CBO认为table scan比index range scan更少的cost;
适用于没有index的链接,或两个大小接近的超大
结果集。
3.Hash join
在oracle7.3中做为NL join的代替方式首次引入的。
大小不一样的结果集进行链接,小的结果集做为驱动表,建立基
于内存的Hash table,大的结果集计算hash value。
下面是图:
Nested Join:
Merge
Hash Join