1. 程式人生 > >表連線三劍客(巢狀迴圈連線,雜湊連線,排序合併連線)

表連線三劍客(巢狀迴圈連線,雜湊連線,排序合併連線)

表連線三劍客(巢狀迴圈連線,雜湊連線,排序合併連線)

1.表連線的定義:

例子1:有一個特別的舞會,男孩子集中在一個房間,女孩子集中在另外一個房間,舞池設定在兩個房間中間.

開始跳舞時,從男孩子中選出一個à然後進入女孩子所在房間à選擇出高度合適的女孩!這種方式成為à NESTED LOOPS JOIN(巢狀迴圈連線)

例子2:男孩子在房間裡面先按身高進行排序à女孩子也在房間按照身高進行排序à男女雙方按照排列好的順序依次出來到舞池中間跳舞

這種方式稱為àHASH連線(PGA中的HASH_AREA_SIZE引數來控制)或者MERGE SORT JOIN(排序合併連線)(PGA中的SORT_AREA_SIZE

引數控制)

2.表連線的特點

(1)巢狀迴圈連線:驅動表返回多少條記錄,被驅動表就反問多少次!

其中例子:

Select/*+ leading(t1) use_nl(t2)*/ from t1,t2 where t1.id = t2.id;

Use_nl表示強制使用巢狀迴圈連線的方式,leading(t1)表示強制先訪問t1,也就是t1表作為驅動表。

不會產生排序操作。支援所有的連線條件,沒有任何限制。

巢狀迴圈連線適用場景:

A.      兩表關聯返回的記錄不多,最佳情況是驅動表結果集僅返回1條或者少量幾條記錄,而被驅動表僅匹配到1條或少量幾條記錄,這種情況即便T1表和T2表的記錄奇大無比,

也是非常迅速  ?????(不明白,不應該是遍歷兩個表嗎??怎麼會很快??)

B.      遇到一些不等值查詢導致雜湊連線和排序合併連線被限制使用。

優化思路:

驅動表的限制條件所在列有索引,被驅動表的連線條件的列有索引。

例如:select * from t1,t2 where t1.id = t2.t1_id and t1.n = 19;

此時如果t1表在n欄位(限制條件)有索引,t2表在t1_id欄位(連線條件)有索引的話,會高效。

解釋:驅動表的限制條件建了索引,會快速的返回1條或幾條記錄,然後再根據連線條件傳遞給被驅動表,而被驅動表此時在該欄位建有索引就會快速的返回記錄。

(2)HASH
連線:在HASH連線中,驅動表和被驅動表都只會訪問0次或者1

Select /*+ leading(t1) use_hash(t2)*/* from t1,t2 where t1.id=t2.id;

雜湊連線並不排序,但是需要消耗記憶體用於建立HASH表。在獲取欄位中根據業務需求儘量少獲取欄位。

雜湊連線不支援不等值連線<>,不支援>和不支援<的連線方式,也不支援like的連線方式

優化思路:

A.      在限制條件列如有適當的索引可以提升效能

B.      增大HASH_AREA_SIZE,一般在記憶體自動管理中,增大PGA的大小即可。

(3)排序合併連線:和HASH連線一樣,只訪問0次或者1次。但是沒有驅動和被驅動表的概念。

Select /*+ ordered use_merge(t2)*/* from t1,t2 where t1.id= t2.id;

排序合併連線需要排序,會消耗記憶體。在獲取欄位中根據業務需求儘量少獲取欄位。

排序合併連線不支援<>,like的連線條件。

巢狀迴圈連線和雜湊連線有驅動順序,驅動表的順序不同將影響表連線的效能,而排序合併連線沒有驅動的概念,無論哪張表在前都無妨。

優化思路:

在連線條件列建立索引,以消除一張表的排序,提升效率。(但是2張表同時建立索引也只會消除一個表的排序)

轉載自:http://blog.itpub.net/25269462/viewspace-764243/