连接发生在一对表和数据来源之间,from子句存在多个表时,优化器决定哪个连接运算对每个表最有效。

 

常见连接方法:嵌套循环连接、散列连接、排序-合并和笛卡尔,每种方法都有一定的适当条件。每个连接方式都有两个分支,访问的第一个表叫驱动表,访问的第二个表叫被驱动表,通常优化器估计回到行最小的表通常作为驱动表。

 

嵌套循环用于表大表小,哈希循环用于等值连接,mergejoin用于不等值连接。

 

nestedloop(嵌套循环):(相关条件列需要索引,驱动表的数据远小于被驱动表)

 

存在两个循环,一个是外部循环,提取驱动表中符合条件的记录。另一个是内部循环,根据外部循环中提取的各项记录连接内表查询相应的记录。由于这两种循环是嵌套进行的,这种连接方法称为嵌套循环连接。

 

特点:

 

1.大表与小表(驱动表)连接,连接方式为等值或不等值。

 

2、驱动表数据小或内表连接的列具有唯一性索引或高度可选的非唯一性索引,效率高。

 

3.可以快速读取结果,集中第一次记录,不必等待结果集整体完全确定。

 

嵌套循环连接返回前几行的记录非常快,因为使用嵌套循环后,不需要在所有循环结束后返回结果集,而是不断返回查询的结果集。在这种情况下,终端用户将迅速获得返回的第一批记录,并等待Oracle内部处理其他记录并返回。如果查询的驱动表的记录数量非常多,或者被驱动表的连接列没有索引或索引,则嵌套循环连接的效率非常低。

 

hashjoin(散列连接)(只适用于等值连接):

 

哈希连接分为两个阶段,如下。

 

1、构建阶段:优化器首先选择比较小的表作为驱动表,用哈希函数计算连接列产生哈希表。通常,这一步是在内存中进行的,所以计算很快。

 

2、检测阶段:优化器用同样的哈希函数计算被驱动表的连接列的结果,与以前形成的哈希表进行检测返回符合条件的记录。在这个阶段,如果被驱动表连接列的值与被驱动表连接列的值不相等,则这些记录将被丢弃而不被探测。

 

特点:

 

1.一般来说,两块相同大小的表连接,初始参数hash_join_enable=true

 

2.只有等价连接,只有CBO模式。

 

3.只有一个源表需要排序,可能比mergejoin快,因为只需要排序一个源表

 

也许比nestedloop快。因为处理内存的hash表比处理b-tree索引快。

 

4.可能使用临时表空间,因此pag_aggregate_target设置较大。

 

哈希连接更适合返回大数据量结果集的连接。

 

mergejoin(排序-合并):两个相互连接的表按连接列的值先排序,排序后形成的结果集再合并提取符合条件的记录(用于>>=<=等情况的连接)

 

特点:

 

1.先对两块表的连接列进行排序后再连接。

2.如果数据选择性和有效索引不足,或者两个表庞大,可能比nestedloop更有效。

3.只有等值连接,才能使用temp表的空间。

 

排序并联比较适合返回大数据量的结果。

 

排序合并连接在数据表预先排序时效率非常高,适用于非等值连接时,如>>=<=等连接(哈希连接只适用于等值连接)

 

笛卡尔积

 

笛卡尔积连接发生在一个表的所有行与另一个表的所有行连接时,因此这个连接的结果集等于两个表的数据行数。在实际应用中不使用或避免这种连接。