關係數據庫技術的精髓就是經過關係表進行規範化的數據存儲,並經過各類錶鏈接技術和各類類型的索引技術來進行信息的檢索和處理。sql
表的三種關聯方式:數據庫
nested loop:從A表抽一條記錄,遍歷B表查找匹配記錄,而後從a表抽下一條,遍歷B表........就是一個二重循環
hash join:將A表按鏈接鍵計算出一個hash表,而後從B表一條條抽取記錄,計算hash值,根據hash到A表的hash來匹配符合條件的記錄
sort merge join:將A,B表都排好序,而後作merge,符合條件的選出
對於三種鏈接,咱們均可以使用hint來強制讓優化器走:use_hash,use_nl,use_merge.緩存
Nested Loop Join服務器
1.執行原理oop
例如:
select t1.*,t2.* from t1,t2 where t1.col1=t2.col2;
訪問機制以下:
for i in (select * from t1) loop ----t1爲驅動表
for j in (select * from t2 where col2=i.col1) loop
display results;
end loop;
end loop;
相似一個嵌套循環
嵌套循環執行時,先是外層循環進入內層循環,並在內層循環終止以後
接着執行外層循環再由外層循環進入內層循環中,當外層循環所有終止時,程序結束
2.步驟以下優化
a.肯定驅動表
b.把inner 表分配給驅動表
c.針對驅動表的每一行,訪問被驅動表的全部行
3.執行計劃大體以下spa
NESTED LOOPS
outer_loop --驅動表
inner_loop
優化器模式爲FIRST_ROWS時,咱們常常會發現有大量的NESTED LOOP
這時,在返回數據給用戶時,咱們沒有必要緩存任何數據,這是nested loop的一大亮點
4.使用場景.net
通常用在鏈接的表中有索引,而且索引選擇性較好(也就是Selectivity接近1)的時候 也就是驅動表的記錄集比較小(<10000)並且inner表須要有有效的訪問方法(Index) 須要注意的是:JOIN的順序很重要,驅動表的記錄集必定要小,返回結果集的響應時間是最快的
5.和索引的關係設計
嵌套循環和索引就像一對孿生兄弟,通常須要共同考量與設計,這從優化器的執行機制能夠看出.
好比,存在2張表,一個10條記錄,一個1000萬條記錄
以小表爲驅動表,則代價爲:10*(經過索引在大表查詢一條記錄的代價)
若是1000萬的大表沒有索引的時候,那麼COST的代價可想而知
所以,在多表鏈接時,注意被驅動表的鏈接字段是否須要建立索引
或者鏈接字段與該表的其餘約束條件字段上是否須要建立複合索引
Sort Merge Joincode
1.執行原理
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,依次交替 比對 歸併,但無所謂驅動
2.使用場景
雖然說,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大概就用在沒有索引,而且數據已經排序的狀況
參考blog:http://blog.csdn.net/dba_waterbin/article/details/8547451