多表链接的三种方式详解 hash join、merge join、 nested loop

在多表联合查询的时候,若是咱们查看它的执行计划,就会发现里面有多表之间的链接方式。多表之间的链接有三种方式:Nested Loops,Hash Join 和 Sort Merge Join.具体适用哪一种类型的链接取决于html

  • 当前的优化器模式 (ALL_ROWS 和 RULE)
  • 取决于表大小
  • 取决于链接列是否有索引
  • 取决于链接列是否排序

下面来介绍三种不一样链接工做方式的不一样:sql

实验sqloop

假若有10000个城市,对应于10个国家(此例子仅仅能够解释join工做的过程)性能

更换优化器,添加索引,会影响下面的执行计划。大数据

drop table country;
CREATE TABLE country (
country_id SMALLINT NOT NULL,
country_name VARCHAR(50) NOT NULL
);

drop table city;
CREATE TABLE city (
city_id VARCHAR(50) NOT NULL,
city_name VARCHAR(50) NOT NULL,
country_id SMALLINT NOT NULL
);

begin
for i in 1 .. 10 loop
insert into country values(i,'country'||i);
end loop;
commit;
end;

begin
for i in 1 .. 10000 loop
insert into city values(i,'city'||i,ceil(i/1000));
end loop;
commit;
end;

一.HASH JOIN:散列链接

Hash join散列链接是CBO 作大数据集链接时的经常使用方式,优化器使用两个表中较小的表(一般是小一点的那个表或数据源)利用链接键(JOIN KEY)在内存中创建散列表,将列数据存储到hash列表中,而后扫描较大的表,一样对JOIN KEY进行HASH后探测散列表,找出与散列表匹配的行。须要注意的是:若是HASH表太大,没法一次构造在内存中,则分红若干个partition,写入磁盘的temporary segment,则会多一个写的代价,会下降效率。优化

这种方式适用于较小的表彻底能够放于内存中的状况,这样总成本就是访问两个表的成本之和。可是在表很大的状况下并不能彻底放入内存,这时优化器会将它分割成若干不一样的分区,不能放入内存的部分就把该分区写入磁盘的临时段,此时要有较大的临时段从而尽可能提升I/O 的性能。ui

能够用USE_HASH(table_name1 table_name2)提示来强制使用散列链接。spa

使用状况:.net

Hash join在两个表的数据量差异很大的时候.3d

clip_image001

二.SORT MERGE JOIN:排序合并链接

Merge Join 是先将关联表的关联列各自作排序,而后从各自的排序表中抽取数据,到另外一个排序表中作匹配。

由于merge join须要作更多的排序,因此消耗的资源更多。 一般来说,可以使用merge join的地方,hash join均可以发挥更好的性能,即散列链接的效果都比排序合并链接要好。然而若是行源已经被排过序,在执行排序合并链接时不须要再排序了,这时排序合并链接的性能会优于散列链接。

可使用USE_MERGE(table_name1 table_name2)来强制使用排序合并链接.

适用状况:

1.RBO模式

2.不等价关联(>,<,>=,<=,<>)

3.HASH_JOIN_ENABLED=false

4. 用在没有索引,而且数据已经排序的状况.

clip_image002

三.NESTED LOOP:嵌套循环链接

Nested loops 工做方式是循环从一张表中读取数据(驱动表outer table),而后访问另外一张表(被查找表 inner table,一般有索引)。驱动表中的每一行与inner表中的相应记录JOIN。相似一个嵌套的循环。

对于被链接的数据子集较小的状况,嵌套循环链接是个较好的选择。在嵌套循环中,内表被外表驱动,外表返回的每一行都要在内表中检索找到与它匹配的行,所以整个查询返回的结果集不能太大(大于1 万不适合),要把返回子集较小表的做为外表(CBO 默认外表是驱动表),并且在内表的链接字段上必定要有索引。固然也能够用ORDERED 提示来改变CBO默认的驱动表。

使用USE_NL(table_name1 table_name2)但是强制CBO 执行嵌套循环链接。

适用状况:

适用于驱动表的记录集比较小(<10000)并且inner表须要有有效的访问方法(Index),而且索引选择性较好的时候.

JOIN的顺序很重要,驱动表的记录集必定要小,返回结果集的响应时间是最快的。

clip_image003

参考

三种join方法的理解

多表链接的三种方式详解 HASH JOIN MERGE JOIN NESTED LOOP

Merge join、Hash join、Nested loop join对比分析

nested loop join探讨

相关文章
相关标签/搜索