排序合併連接 (Sort Merge Join)是一種兩個表在做連接時用排序操作(Sort)和合並操作(Merge)來得到連接結果集的連接方法。
對於排序合併連接的優缺點及適用場景如下:
a,通常情況下,排序合併連接的執行效率遠不如哈希連接,但前者的使用範圍更廣,因爲哈希連接只能用於等值連接條件,而排序合併連接還能用於其他連接條件(如<,<=,>.>=)
b,通常情況下,排序合併連接並不適合OLTP類型的系統,其本質原因是對於因爲OLTP類型系統而言,排序是非常昂貴的操作,當然,如果能避免排序操作就例外了。
oracle表之間的連接之排序合併連接(Merge Sort Join),其特點如下:
1,驅動表和被驅動表都是最多隻被訪問一次。
2,排序合併連接的表無驅動順序。
3,排序合併連接的表需要排序,用到SORT_AREA_SIZE。
4,排序合併連接不適用於的連接條件是:不等於<>,like,其中大於>,小於<,大於等於>=,小於等於<=,是可以適用於排序合併連接
5,排序合併連接,如果有索引就可以排除排序。
下面我來做個實驗來證實如上的結論:
具體的測試基礎表請查看本人Blog 如下鏈接:
oracle表連接之----〉嵌套循環(Nested Loops Join)
SQL> select /*+ ordered use_merge(t2)*/ * from t1,t2 where t1.id=t2.t1_id;
SQL> select sql_id, child_number, sql_text from v$sql where sql_text like '%use_merge%';
SQL_ID CHILD_NUMBER SQL_TEXT
------------- ------------ --------------------------------------------------------------------------------
85u4h9hfqa5ar 0 select sql_id, child_number, sql_text from v$sql where sql_text like '%use_merg
6xph9fhapys39 0 select /*+ ordered use_merge(t2)*/ * from t1,t2 where t1.id=t2.t1_id
SQL> select * from table(dbms_xplan.display_cursor('6xph9fhapys39',0,'allstats last'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID 6xph9fhapys39, child number 0
-------------------------------------
select /*+ ordered use_merge(t2)*/ * from t1,t2 where t1.id=t2.t1_id
Plan hash value: 412793182
--------------------------------------------------------------------------------
| Id | Operation | Name | Starts
| E-Rows | A-Rows | A-Time | Buf
--------------------------------------------------------------------------------
| 1 | MERGE JOIN | | 1 | 100 | 100 |00:00:00.07 |
| 2 | SORT JOIN | | 1 | 100 | 100 |00:00:00.01 |
| 3 | TABLE ACCESS FULL| T1 | 1 | 100 | 100 |00:00:00.01 |
|* 4 | SORT JOIN | | 100 | 100K| 100 |00:00:00.07 |
| 5 | TABLE ACCESS FULL| T2 |
1 | 100K| 100K|00:00:00.01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("T1"."ID"="T2"."T1_ID")
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
filter("T1"."ID"="T2"."T1_ID")
Note
-----
- dynamic sampling used for this statement
26 rows selected
從上面的實驗可以看出排序合併連接和HASH連接時一樣的,T1和T2 表都只會被訪問0次或者1次。
select /*+ ordered use_merge(t2)*/ * from t1,t2 where t1.id=t2.t1_id and 1=2;此語句T1和T2表就會是被訪問0次。自己可以做試驗測試下。