oracle執行計劃之-錶鏈接方式

轉載自:http://blog.csdn.net/tianlesoftware/article/details/5826546sql

在多表聯合查詢的時候,若是咱們查看它的執行計劃,就會發現裏面有多表之間的鏈接方式。 以前打算在sqlplus中用執行計劃的,可是格式看起來有點亂,就用Toad 作了3個截圖。網絡

   

 

 

 

 

 

 

 

 

 

 

從3張圖裏咱們看到了幾點信息:oop

1.       CBO 使用的ALL_ROWS模式性能

Oracle Optimizer CBO RBO大數據

http://blog.csdn.net/tianlesoftware/archive/2010/08/19/5824886.aspx優化

 

2.       表之間的鏈接用了hash Join, Nested loops,Sort Merge Join.net

 

 

多表之間的鏈接有三種方式:Nested Loops,Hash Join 和 Sort Merge Join. 下面來介紹三種不一樣鏈接的不一樣:視頻

 

 

一. NESTED LOOP:blog

對於被鏈接的數據子集較小的狀況,嵌套循環鏈接是個較好的選擇。在嵌套循環中,內表被外表驅動,外表返回的每一行都要在內表中檢索找到與它匹配的行,所以整個查詢返回的結果集不能太大(大於1 萬不適合),要把返回子集較小表的做爲外表(CBO 默認外表是驅動表),並且在內表的鏈接字段上必定要有索引。固然也能夠用ORDERED 提示來改變CBO默認的驅動表,使用USE_NL(table_name1 table_name2)但是強制CBO 執行嵌套循環鏈接。排序

        

Nested loop通常用在鏈接的表中有索引,而且索引選擇性較好的時候.

 

步驟:肯定一個驅動表(outer table),另外一個表爲inner table,驅動表中的每一行與inner表中的相應記錄JOIN。相似一個嵌套的循環。適用於驅動表的記錄集比較小(<10000)並且inner表須要有有效的訪問方法(Index)。須要注意的是:JOIN的順序很重要,驅動表的記錄集必定要小,返回結果集的響應時間是最快的。

cost = outer access cost + (inner access cost * outer cardinality)

 

| 2 | NESTED LOOPS | | 3 | 141 | 7 (15)|
| 3 | TABLE ACCESS FULL | EMPLOYEES | 3 | 60 | 4 (25)|
| 4 | TABLE ACCESS BY INDEX ROWID| JOBS | 19 | 513 | 2 (50)|
| 5 | INDEX UNIQUE SCAN | JOB_ID_PK | 1 | | |

EMPLOYEES爲outer table, JOBS爲inner table.

 

 

二. HASH JOIN :

散列鏈接是CBO 作大數據集鏈接時的經常使用方式,優化器使用兩個表中較小的表(或數據源)利用鏈接鍵在內存中創建散列表,而後掃描較大的表並探測散列表,找出與散列表匹配的行。

這種方式適用於較小的表徹底能夠放於內存中的狀況,這樣總成本就是訪問兩個表的成本之和。可是在表很大的狀況下並不能徹底放入內存,這時優化器會將它分割成若干不一樣的分區,不能放入內存的部分就把該分區寫入磁盤的臨時段,此時要有較大的臨時段從而儘可能提升I/O 的性能。

也能夠用USE_HASH(table_name1 table_name2)提示來強制使用散列鏈接。若是使用散列鏈接HASH_AREA_SIZE 初始化參數必須足夠的大,若是是9i,Oracle建議使用SQL工做區自動管理,設置WORKAREA_SIZE_POLICY 爲AUTO,而後調整PGA_AGGREGATE_TARGET 便可。

        

Hash join在兩個表的數據量差異很大的時候.

 

步驟:將兩個表中較小的一個在內存中構造一個HASH表(對JOIN KEY),掃描另外一個表,一樣對JOIN KEY進行HASH後探測是否能夠JOIN。適用於記錄集比較大的狀況。須要注意的是:若是HASH表太大,沒法一次構造在內存中,則分紅若干個partition,寫入磁盤的temporary segment,則會多一個寫的代價,會下降效率。

cost = (outer access cost * # of hash partitions) + inner access cost

 

--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 665 | 13300 | 8 (25)|
| 1 | HASH JOIN | | 665 | 13300 | 8 (25)|
| 2 | TABLE ACCESS FULL | ORDERS | 105 | 840 | 4 (25)|
| 3 | TABLE ACCESS FULL | ORDER_ITEMS | 665 | 7980 | 4 (25)|
--------------------------------------------------------------------------

ORDERS爲HASH TABLE,ORDER_ITEMS掃描

 

 

三.SORT MERGE JOIN

一般狀況下散列鏈接的效果都比排序合併鏈接要好,然而若是行源已經被排過序,在執行排序合併鏈接時不須要再排序了,這時排序合併鏈接的性能會優於散列鏈接。可使用USE_MERGE(table_name1 table_name2)來強制使用排序合併鏈接.

        

Sort Merge join 用在沒有索引,而且數據已經排序的狀況.

 

cost = (outer access cost * # of hash partitions) + inner access cost

 

步驟:將兩個表排序,而後將兩個表合併。一般狀況下,只有在如下狀況發生時,纔會使用此種JOIN方式:

1.RBO模式

2.不等價關聯(>,<,>=,<=,<>)

3.HASH_JOIN_ENABLED=false

4.數據源已排序

 

 

四.  三種鏈接工做方式比較:

     

       Hash join的工做方式是將一個表(一般是小一點的那個表)作hash運算,將列數據存儲到hash列表中,從另外一個表中抽取記錄,作hash運算,到hash 列表中找到相應的值,作匹配。

        

Nested loops 工做方式是從一張表中讀取數據,訪問另外一張表(一般是索引)來作匹配,nested loops適用的場合是當一個關聯表比較小的時候,效率會更高。

 

         Merge Join 是先將關聯表的關聯列各自作排序,而後從各自的排序表中抽取數據,到另外一個排序表中作匹配,由於merge join須要作更多的排序,因此消耗的資源更多。 一般來說,可以使用merge join的地方,hash join均可以發揮更好的性能。

 

 

 

整理自網絡

------------------------------------------------------------------------------

Blog: http://blog.csdn.net/tianlesoftware

網上資源: http://tianlesoftware.download.csdn.net

相關視頻:http://blog.csdn.net/tianlesoftware/archive/2009/11/27/4886500.aspx

DBA1 羣:62697716(滿); DBA2 羣:62697977(滿)

DBA3 羣:63306533;     聊天 羣:40132017

相關文章
相關標籤/搜索