哈希连接
下面的内容描述哈希连接(hash join)的运行机制。首先,介绍它们的基本行为以及两表连接与四表连接的例子,接着介绍哈希连接执行过程中使用到的工作区。最后介绍一种特殊的优化技巧― 索引连接(index join)。
哈希连接处理的两个数据集分别称为构造输入(build input )和探测输入(probe input )。构造输入为左节点,探测输入为右节点。如图10—11所示,构造输入的每行记录都会被用来在内存中(或者临时空间,如果没有足够多的内存可用的话)构造哈希表。注意,哈希键值(hash key )是根据连接条件使用的字段计算出来的。当哈希表已经包含构造输入的所有数据时,就开始处理探测输入了。探测输入的每行记录都会被拿来对哈希表进行探测以找出符合连接条件的记录。显然,只有匹配的记录会返回。
哈希连接有以下特征:
口每个子节点只会执行一次。
口哈希表仅由左节点来构造。因而,一般采用最小的那个节点来构造。
口只有在左节点完全处理完毕后,才会返回第一条记录。
口不支持交叉连接、条件连接和分区外连接。
两表连接
下面是一个简单的处理两表哈希连接的执行计划。它也说明了如何通过指定1 eadlng 和盯e . has 卜提示来强制使用哈希连接。
SELECT /*+ leading(t1) use_hash(t2) */ *
FROM t1,t2
WHERE t1.id =t2.t1_id
AND t1.n=19
哈希连接(HASH JOIN)是一个非相关联合型操作,这一点己经在第6章中提及。这表明它的两个子数据集只会相互独立地处理一次。在这个例子中,执行计划的处理过程可以总结如下。
口通过全表扫描读出表t1的所有记录,应用限制条件n=19,根据返回的结果记录构造一个哈希表。为了构造这个哈希表,需要在连接条件使用的字段(记)上应用哈希函数。
口通过全表扫描读出表t2 的所有记录,在连接条件使用的字段(t1_id)上应用哈希函数,接着探测哈希表。如果找到匹配记录,就返回结果记录。
哈希连接(作为非相关联合型操作)最重要的限制是无法将索引应用到连接条件上。这意味着只有当限制条件存在的时候才能使用索引作为访问路径.例如,如果限制条件n=19 能提供较好的选择性,创建一个索引就显得必要了。
CREATE INDEX t1_n ON t1(n)
事实上,有这个索引的时候,可能会使用下面的这个执行计划。注意,表t1不再是通过全表扫描被访问。
索引连接
索引连接只能用哈希连接方法来执行。因此,可以认为它们是哈希连接的一个特例。它的目的是通过对同一张表的不同索引做连接以避免做代价较高的整表扫描。当一张表有多个索引字段,并且在SQL语句只引用很少几个字段的时候,索引连接就很有用了。下面的语句就是一个这方面的例子。注意,虽然这个语句只引用了一张表,然而无论你怎么想,它却执行了连接操作而不是一个单表扫描。另外需要特别注意的是,这两个数据集之间的连接条件是基于rowid 的。这个例子还演示了如何通过index_join 提示强制进行索引连接。
SELECT /* + index_join(t4 t4_n t4_pk)*/id , n
FROM t4
WHERE id BETWEEN 10 AND 20
AND n <100