三大表連接方式詳解之Nested loop join和 Sort merge join


在早期版本,Oracle提供的是nested-loop join,兩表連接就相當於二重循環,假定兩表分別有m行和n行
       如果內循環是全表掃描,時間復雜度就是O(m*n)
       如果內循環是索引掃描,時間復雜度就是O(m*㏒n)
       而hash join的時間復雜度是O(m*n)
       因此10g后,hash join成為缺省的連接方法
       
       對於三種連接,我們都可以使用hint來強制讓優化器走:use_hash,use_nl,use_merge
       
       三大連接方法的大綱先列如下:
       
       nested loop
       從A表抽一條記錄,遍歷B表查找匹配記錄,然后從a表抽下一條,遍歷B表。。。
       就是一個二重循環
       
       hash join
       將A表按連接鍵計算出一個hash表,然后從B表一條條抽取記錄,計算hash值,根據hash到A表的hash來匹配符合條件的記錄
       
       sort merge join
       將A,B表都排好序,然后做merge,符合條件的選出
       
       接下來分別談談各種連接
       
       ㈠ Nested Loop Join
       
       ⑴ 執行原理
       例如:
       select t1.*,t2.* from t1,t2 where t1.col1=t2.col2;
       訪問機制如下:
       for i in (select * from t1) loop
         for j in (select * from t2 where col2=i.col1) loop
         display results;
         end loop;
         end loop;
       類似一個嵌套循環
       嵌套循環執行時,先是外層循環進入內層循環,並在內層循環終止之后
       接着執行外層循環再由外層循環進入內層循環中,當外層循環全部終止時,程序結束
       
       ⑵ 步驟如下:
       
       ① 確定驅動表
       ② 把inner 表分配給驅動表
       ③ 針對驅動表的每一行,訪問被驅動表的所有行
       
       ⑶執行計划大致如下:
       
       NESTED LOOPS
       outer_loop
       inner_loop
       
       優化器模式為FIRST_ROWS時,我們經常會發現有大量的NESTED LOOP
       這時,在返回數據給用戶時,我們沒有必要緩存任何數據,這是nested loop的一大亮點
       
       
       ⑷ 使用場景
          一般用在連接的表中有索引,並且索引選擇性較好(也就是Selectivity接近1)的時候
          也就是驅動表的記錄集比較小(<10000)而且inner表需要有有效的訪問方法(Index)
          需要注意的是:JOIN的順序很重要,驅動表的記錄集一定要小,返回結果集的響應時間是最快的
          
       ⑸ 和索引的關系
       
          嵌套循環和索引就像一對孿生兄弟,一般需要共同考量與設計
          這從優化器的執行機制可以看出,比如,存在2張表,一個10條記錄,一個1000萬條記錄
          以小表為驅動表,則代價為:10*(通過索引在大表查詢一條記錄的代價)
          如果1000萬的大表沒有索引的時候,那么COST的代價可想而知
          因此,在多表連接時,注意被驅動表的連接字段是否需要創建索引
          或者連接字段與該表的其他約束條件字段上是否需要創建復合索引
       
       
       ㈡ Sort Merge Join
          
          ⑴ 執行原理
          例如:
          select t1.*,t2.* from t1,t2 where t1.id=t2.id;
          訪問機制如下:
          訪問t1,並order by t1_1.id,這里的id代表連接字段
          訪問t2,並order by t2_1.id
          join t1_1.id = t2_1.id,依次交替 比對 歸並,但無所謂驅動
          
     
          
          ⑵ 使用場景
             雖說,hash join就是用來替代sj的,但如果你的服務器的CPU資源和MEM資源都很緊張的時候,建議用SORT MERGE JOIN
             因為hash join比sort merge join需要的資源更多。特別是cpu
             10g sql tuning 文檔上寫道:
             On the other hand, sort-merge joins can perform better than hash joins if both of the following conditions are met:
             The row sources are already sorted. 
             A sort operation does not have to be done.
             所以,sj大概就用在沒有索引,並且數據已經排序的情況
         
       由於hash join比較重要也比較難理解,所以這里Think就單獨為它開在下一篇博客里頭了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM