1. 程式人生 > >oracle 表之間連線型別

oracle 表之間連線型別

排序- - 合併連線 (Sort Merge Join(SMJ))

                 排序是一個費時,費資源的操作,特別對於大表。基於這個原因,SMJ 經常不是一個特別有效的連線方法,但是如果2 行源都已經預先排序,則這種連線方法的效率較高。

 巢狀迴圈 (Nested Loops(NL))

              該連線過程是一個2 層巢狀迴圈,則外層迴圈的次數越少越好,這也就是我們為什麼將小表或返回較小

行源的表作為驅動表用於外層迴圈的理論依據。但是這個理論只是一般指導原則,因為遵循這個理論並不能總保證使語句產生的I / O 次數最少。

       如果駕駛行源(驅動表或者外部表比較小,並且在內行源(被驅動表或者被探查表內部表上有唯一索引,或有高選擇性非唯一索引時,使用這種方法可以。得到較好的效率巢狀迴圈有其它連線方法沒有的的一個優點是可以先返回已經連線的行,而不必等待所有的連線操作處理完才返回資料,這可以實現快速的響應時間。

       如果不使用並行操作,最好的驅動表是那些應用了where

限制條件後,可以返回較少行資料的的表,所以大表也可能稱為驅動表,關鍵看限制條件。對於並行查詢,我們經常選擇大表作為驅動表,因為大表可以充分利用並行功能。當然,有時對查詢使用並行操作並不一定會比查詢不使用並行操作效率高,因為最後可能每個表只有很少的行符合限制條件,而且還要看你的硬體配置是否可以支援並行(如是否有多個CPU,多個硬碟控制器)。

 理論上來說比NLSMJ更高效,而且只用在CBO優化器中。

雜湊連線 (Hash Join)

        較小的row source被用來構建hash tablebitmap,第2row source

被用來被hansed,並與第一個row source生成的hash table進行匹配,以便進行進一步的連線。Bitmap被用來作為一種比較快的查詢方法,來檢查在hash table中是否有匹配的行。特別的,當hash table比較大而不能全部容納在記憶體中時,這種查詢方法更為有用。這種連線方法也有NL連線中所謂的驅動表的概念,被構建為hash tablebitmap的表為驅動表,當被構建的hash tablebitmap能被容納在記憶體中時,這種連線方式的效率極高。  要使雜湊連線有效,需要設定HASH_JOIN_ENABLED=TRUE,預設情況下該引數為TRUE,另外,不要忘了還要設定hash_area_size引數,以使雜湊連線高效執行,因為雜湊連線會在該引數指定大小的記憶體中執行,過小的引數會使雜湊連線的效能比其他連線方式還要低。

笛卡兒乘積(乘積) 

        當兩個row source做連線,但是它們之間沒有關聯條件時,就會在兩個row source中做笛卡兒乘積,這通常由編寫程式碼疏漏造成(即程式設計師忘了寫關聯條件)。笛卡爾乘積是一個表的每一行依次與另一個表中的所有行匹配。在特殊情況下我們可以使用笛卡兒乘積,如在星形連線中,除此之外,我們要儘量避免使用笛卡兒乘積。

 

總結:

 在哪種情況下用哪種連線方法比較好:

1.排序 - - 合併連線(Sort Merge Join, SMJ)

   對於非等值連線,這種連線方式的效率是比較高的。

   如果在關聯的列上都有索引,效果更好。

   對將2個較大的row source做連線,該連線方法比NL連線要好些。

   但是如果sort merge返回的row source過大,則又會導致使用過 多的rowid在表中查詢資料時,資料庫效能下降,因為過多的I/O

2.巢狀迴圈(Nested Loops, NL)

     如果driving row source(外部表)比較小,並且在inner row source(內部表)上有唯一索引,或有高選擇性非唯一索引時,使用這種方法可以得到較好的效率。

   NESTED LOOPS有其它連線方法沒有的的一個優點是:可以先返回已經連線的行,而不必等待所有的連線操作處理完才返回資料,這可以實現快速的響應時間

3.雜湊連線(Hash Join, HJ)

    此方法是在oracle7後來引入的,使用了比較先進的連線理論,

    其效率應該好於其它2種連線,但是這種連線只能用在

    CBO優化器中,而且需要設定合適的hash_area_size引數,才能取得較好的效能。

    在2個較大的row source之間連線時會取得相對較好的效率,在一row source較小時則能取得更好的效率。

    只能用於等值連線中