Oracle中表的連線及其調整(二)

why566發表於2008-07-23
三、 雜湊連線(Hash join)
    雜湊連線分為兩個階段,如下。
1、 構建階段:最佳化器首先選擇一張小表做為驅動表,運用雜湊函式對連線列進行計算產生一張雜湊表。通常這個步驟是在記憶體(hash_area_size)裡面進行的,因此運算很快。
2、探測階段:最佳化器對被驅動表的連線列運用同樣的雜湊函式計算得到的結果與前面形成的雜湊表進行探測返回符合條件的記錄。這個階段中如果被驅動表的連線列的值沒有與驅動表連線列的值相等的話,那麼這些記錄將會被丟棄而不進行探測。關於雜湊連線更深層次的原理可以參考Itpub上網友logzgh發表的 “hash join演算法原理”帖子(http://www.itpub.net/showthread.php?threadid=315494)。

以下為雜湊連線的一個例子:
 
Roby@XUE> select /*+ use_hash(emp,dept) */ mp.ename,dept.dname 
2  from emp,dept
3  where emp.deptno=dept.deptno;

ENAME      DNAME
---------- --------------
WARD       SALES
JONES      RESEARCH
MARTIN     SALES
BLAKE      SALES
CLARK      ACCOUNTING
SCOTT      RESEARCH
KING       ACCOUNTING
TURNER     SALES
ADAMS      RESEARCH
JAMES      SALES
FORD       RESEARCH
MILLER     ACCOUNTING

12 rows selected.

Execution Plan
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    12 |   264 |     7  (15)| 00:00:01 |
|*  1 |  HASH JOIN         |      |    12 |   264 |     7  (15)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| DEPT |     4 |    52 |     3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| EMP  |    12 |   108 |     3   (0)| 00:00:01 |

    在這個查詢中最佳化器首先選擇dept這張表為驅動表,對列deptno運算雜湊函式構建一張雜湊表,然後再對被驅動表emp的deptno列運算同樣的雜湊函式計算得到的結果進行探測,最終連線得出符合條件的記錄。
同巢狀迴圈外連線一樣,雜湊迴圈外連線的驅動表同樣是沒有符合條件關聯的那張表。如下述例子:
  
Roby@XUE> select /*+ use_hash(emp,dept) */ emp.ename,dept.dname
2 from emp,dept
3 where emp.deptno=dept.deptno(+);
ENAME DNAME
---------- --------------
MILLER ACCOUNTING
KING ACCOUNTING
CLARK ACCOUNTING
FORD RESEARCH
ADAMS RESEARCH
SCOTT RESEARCH
JONES RESEARCH
JAMES SALES
TURNER SALES
BLAKE SALES
MARTIN SALES
WARD SALES
ALLEN
SMITH
14 rows selected.
Execution Plan
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 308 | 7 (15)| 00:00:01 |
|* 1 | HASH JOIN OUTER | | 14 | 308 | 7 (15)| 00:00:01 |
| 2 | TABLE ACCESS FULL| EMP | 14 | 126 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| DEPT | 4 | 52 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
    雜湊連線比較適用於返回大資料量結果集的連線。使用雜湊連線必須是在CBO模式下,引數hash_join_enabled設定為true,且只適用於等值連線。從Oracle9i開始,雜湊連線由於其良好的效能漸漸取代了原來的排序合併連線。
 
四、跟表連線有關的幾個HINT
(1、)use_nl(t1,t2):表示對錶t1、t2關聯時採用巢狀迴圈連線。
(2、)use_merge(t1,t2):表示對錶t1、t2關聯時採用排序合併連線。
(3、)use_hash(t1,t2):表示對錶t1、t2關聯時採用雜湊連線。
(4、)leading(t):表示在進行表連線時,選擇t為驅動表。
(5、)ordred:要求最佳化器按from列出的表順序進行連線。

需要注意的是在Oracle使用hint時,如果SQL語句中表用別名的話,那麼hint中必須使用表的別名,否則hint將不會生效。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7478833/viewspace-407192/,如需轉載,請註明出處,否則將追究法律責任。

相關文章