oracle錶鏈接方式

在作表join的時候, Oracle有三種方式, 與其說有三種方式, 不如說是三種策略。 sql

分別是: oracle

 

  • sort merge join(SMJ)
  • nest loop(NL)
  • hash join(HJ)

根據個人理解來說講這三種策略。 oop

 

首先講講Row Source, 根據Oracle官方的解釋, 性能

Row source is a row set returned by a step in the execution plan along with a control structure that can iteratively process the rows. The row source can be a table, a view or result of a join or grouping operation. spa

 

總之, Row source是oracle根據執行計劃生成的可操做數據集, 這種說法比Table更爲嚴謹,由於join的兩側多是view或者其餘的object. code

 

1) sort merge join. 排序

 

例如: 索引

select * from t1 inner join t2 on t1.id=t2.id 內存

首先會把row source1(t1)先載入內存, 進行排序, 而後把row source2(t2)載入內存,進行排序,而後進行merge操做。 資源

什麼是merge 操做?就是將兩邊的行按照鏈接條件連起來, (t1.id=t2.id)。

不難看出,這種方式將須要鏈接的兩張表中的列都放到內存中,而後進行排序,而排序是一個消耗資源的操做,這樣對於兩張比較大的表,性能恐怕會比較差。

因此, 這種策略適合於表比較小, 或者在鏈接列上有索引的表。由於索引列已經排過序了。

 

 

2) Nested loops

選定一張表作爲驅動表,Oracle會遍歷驅動表中的每一行,根據鏈接條件去匹配第二張表中的行。

好比第一張表中有50行數據, 第二張表中有100行數據, 這樣遍歷的時間約等於50*100+50*磁頭切換時間

若是選擇第二張表做爲驅動表,遍歷時間約等於100*50+100*磁頭切換時間。

可見使用小表做爲驅動表能夠減小I/O,性能會比較好。

 

例如:

select from t1 inner join t2 on t1.id=t2.id

以上的這個hint 表明的是按照sql中指定的表順序進行鏈接。也就是我把t1做爲驅動表(Driving table).

Orace會根據t1中的每一行, 去尋找t2中知足t1.id=t2.id的行,而後返回到結果集。

 

不難看出, 若是在內部表的查詢列上有索引的話, 查詢的效率將提高。

 

聽說,對於可並行執行的大表, 使用分區了的大表做爲Driving table,性能會比較好,由於會在每一個分區上並行執行,可是取決於硬件是否支持多個磁盤,多個CPU並行執行,這個我並無試過,因此不敢妄加定論。

 

3) Hash Join

僅針對CBO有效。

使用較小的Row source 做爲Hash table和Bitmap. 而第二個row source被hashed,根據bitmap與第一個row source生成的hash table 相匹配,bitmap查找的速度極快。

 

例如:

select   * from t1 inner join t2 on t1.id=t2.id

 

特別的,當Hash Table很大而不能所有留存在內存中的時候,這種Join策略更爲實用。

 

可是,因爲Bitmap自己的限制, 這種join策略只適用在等值鏈接的狀況下。

 

並且,在計算Hash Table的時候, 須要考慮系統Hash_Area_Size參數設置。

 

show parameter hash_area_size