多表鏈接的三種方式詳解 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探討

相關文章
相關標籤/搜索