12 排序合併連線(SORT MERGE JOIN)--優化主題系列
select * from a,b where a.id<=b.id;這個一般都走排序合併連線
排序合併連線(SORTMERGE JOIN)
前文提到巢狀迴圈以及雜湊連線,他們都有驅動表概念。排序合併連線沒有驅動表一說,兩個表/行源是對等關係。排序合併連線原理是先對兩個表/行源根據JOIN列進行排序(當然了排序的時候要踢出不符合where條件的列),然後再進行連線。排序合併連線可以處理非等值JOIN。有時候,出現了非等值JOIN,還非得走SORT MERGEJOIN不可。根據排序合併的原理,我們知道排序合併連線其實很耗費資源,因為要對2個表/結果集進行排序,所以一般情況下,CBO是不會選擇走
排序合併連線是個垃圾下面解釋下
select * from a, b where a.id>b.id;
A 1000W行
B 500W行
1.使用HINT
2.非等值JOIN
3.有一個表或者2個表都已經排序好了
4.JOIN列有索引,對索引進行INDEXFULL SCAN(請自己複習前文的訪問路徑)返回有序的結果,再和另外的表進行JOIN。
INDEX FULL SCAN----TABLE ACCESS BY INDEX ROWID
這種是不是只適合表資料很少
假如說有 1000W行
如果走INDEXFULL SCAN ----TABLE ACCESS BY INDEX ROWID
INDEX FULL SCAN+TABLE ACCESS BY INDEX ROWID 如果很大會比全表+排序慢50倍
下面舉個例子(基於SCOTT,Oracle11gR2):
alter session set statistics_level=all;
select ename, job, sal, dname, loc from emp, dept whereemp.deptno = dept.deptno;
select * fromtable(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));
NL 的迴圈是不是要進行
排序合併連線要在記憶體對比
排序合併連線
其實要返回資料量小的在上面
類似驅動表的角色
排序合併連線為什麼垃圾?
1. 排序而且2邊都排序
2. 排序之後要進行類似NL的演算法
排序合併是不是要耗費PGA?
這兩個表訪問了幾次??ID=2 3這裡根據哪個列排序的??deptno
ID=2 3返回多少條記錄4條對吧
ID=4這裡執行了多少次??4次吧
我現在是不是有2個已經排序過的結果集??
第一個排序是不是返回4條結果??
排序查詢演算法是不是取一條結果跟另外已經排序的結果進行比較有4個結果就比較4次
這個演算法類似NL嗎
排序合併連線是不是垃圾又要排序還要類似NL操作
假設兩個表很大排序的結果太大了比如有100W條記錄是不是要找100W次??
排序完了之後還要進行類似NL的演算法這個時候CPU果斷悲劇
但是這個時候的NL又要比真正的NL要優化因為是在記憶體中進行的
排序合併連線一般看不到很少用資料量少走排序合併連線沒問題資料量大 CPU容易100% PGA也滿了
那為什麼有時候必須走排序合併連線呢??
因為條件是非等值的不能走HASH JOIN更不能走NL因為NL不是在記憶體中進行搜尋的需要消耗磁碟I/O
但是排序合併連線是消耗CPU一般來說 I/O消耗比CPU消耗更嚴重