出自:http://www.itpub.net/thread-207865-1-1.htmlhtml
通常常見的Oracle數據庫鏈接有3種:算法
Nested Loop,Merge,Hash Join數據庫
1.嵌套循環聯接NL(Neeted Loop)
嵌套循環聯接也稱爲嵌套迭代,它將一個聯接輸入用做外部輸入表(顯示爲圖形執行計劃中的頂端輸入),將另外一個聯接輸入用做內部(底端)輸入表。外部循環逐行消耗外部輸入表。oracle
內部循環爲每一個外部行執行,在內部輸入表中搜索匹配行。最簡單的狀況是,搜索時掃描整個表或索引;這稱爲單純嵌套循環聯接。異步
若是搜索時使用索引,則稱爲索引嵌套循環聯接。函數
若是將索引生成爲查詢計劃的一部分(並在查詢完成後當即將索引破壞),則稱爲臨時索引嵌套循環聯接。查詢優化器考慮全部這些不一樣形式。oop
若是外部輸入很小而內部輸入很大且預先建立了索引,則嵌套循環聯接尤爲有效。優化
在許多小事務中(如那些隻影響較小的一組行的事務),索引嵌套循環聯接遠比合並聯接和哈希聯接優越。但在大查詢中,嵌套循環聯接一般不是最佳選擇。.net
總而言之,nested loop適合於關聯2個表結果集小的,並且關聯字段上面存在索引的數據。線程
2.合併聯接(Merge)
合併聯接要求兩個輸入都在合併列上排序,而合併列由聯接謂詞的等效 (WHERE) 子句定義。查詢優化器通常掃描索引(若是在適當的一組列上存在一個索引),或在合併聯接的下面放一個排序運算符。在不多的狀況下,雖然可能有多個等效子句,但只用其中一些可用的等效子句得到合併列。
因爲每一個輸入都已排序,Merge Join 運算符將獲取每一個輸入中的行並將其進行比較。例如,對於內聯接操做,若是行相等則返回。若是行不相等,則廢棄值較小的行並從該輸入中得到另外一行。這一過程將重複進行,直處處理完全部的行爲止。
合併聯接操做能夠是常規操做,也能夠是多對多操做。多對多合併聯接使用臨時表存儲行。若是每一個輸入中有重複值,則在處理其中一個輸入中的每一個重複項時,另外一個輸入必須重繞到重複項的開始位置。
若是存在駐留謂詞,全部知足合併謂詞的行都將對該駐留謂詞取值,而後只返回那些知足該駐留謂詞的行。
合併聯接自己的速度很快,但若是須要排序操做,選擇合併聯接就會很是費時。然而,若是數據量很大且可以從現有 B 樹索引中得到預排序的所需數據,則合併聯接一般是最快的可用聯接算法。
3.哈希聯接(Hash Join)
哈希聯接有兩種輸入:生成輸入和探測輸入。查詢優化器指派這些角色,使兩個輸入中較小的那個做爲生成輸入。
哈希聯接可用於許多類型的集合匹配操做:內聯接,左向外聯接、右向外聯接和完整外聯接,左向半聯接和右向半聯接、交集、聯合和差分。並且,哈希聯接的變化形式可以進行重複項刪除和分組操做(如 SUM(salary) GROUP BY department)。這些修改對生成和探測角色只使用一個輸入。
與合併聯接類似,只有當聯接謂詞中至少有一個等效 (WHERE) 子句時才能使用哈希聯接。然而,聯接通常用於重組合由主鍵和外鍵之間的等效謂詞表達的關係,所以大多數聯接至少有一個等效子句。用等效謂詞表達的列集合稱爲哈希鍵,由於這些列有助於哈希函數。還能夠有附加的謂詞,而且能夠將這些謂詞取值爲駐留謂詞以與哈希值比較分開。哈希鍵能夠是表達式,只要能從單個行中的列對其進行排它計算。在分組操做中,按列表分組的列是哈希鍵。在交集等集合操做中以及刪除複製項時,哈希鍵由全部列組成。
關於哈希鏈接的補充:
內存中的哈希聯接
哈希聯接先掃描或計算整個生成輸入,而後在內存中生成哈希表。根據爲哈希鍵計算出的哈希值,將每行插入哈希存儲桶。若是整個生成輸入比可用內存少,則能夠將全部行都插入哈希表中。生成階段後接着是探測階段。一次一行地對整個探測輸入進行掃描或計算,併爲每一個探測行計算哈希鍵的值,掃描相應的哈希存儲桶並生成匹配項。
Grace 哈希聯接
若是生成輸入不適合內存,哈希聯接將分步進行。每一步都包括生成階段和探測階段。首先,消耗整個生成和探測輸入並(使用哈希鍵上的哈希函數)將其分區爲多個文件。這類文件的數目稱爲分區輸出端。經過使用哈希鍵上的哈希函數,能夠保證任意兩個聯接記錄必在相同的文件對中。所以,聯接兩個大輸入的任務簡化爲相同任務的多個較小的實例。而後將哈希聯接應用於每對分區文件。
遞歸哈希聯接
若是生成輸入很是大,以致於標準外部合併排序的輸入須要多個合併級別,則須要多個分區步驟和多個分區級別。若是隻有某些分區較大,則只需對這些分區使用附加的分區步驟。爲使全部的分區步驟儘量快,將使用大的異步 I/O 操做以便單個線程就能使多個磁盤驅動器繁忙工做。
錶鏈接用法介紹:
1.何時使用NL
必須有一個table擁有index;
只用一個table有index時,選擇沒有index的table做爲驅動表;
當兩個table都有index時,選擇結果集較小的table做爲驅動表 (CBO),RBO會選from的最後一個表作驅動表;
適用於有index的鏈接,兩個有大小差別的結果集,數據量較小。
2.Merge Join
合併列要求排序;
在不使用index的狀況下使用MR join:
在鏈接table的字段上不存在可用的index;
查詢將返回兩個table中大部分的數據塊;
CBO認爲table scan比index range scan更少的cost;
適用於沒有index的鏈接,或兩個大小接近的超大
結果集。
3.Hash join
在oracle7.3中做爲NL join的代替方式首次引入的。
大小不一樣的結果集進行鏈接,小的結果集做爲驅動表,建立基
於內存的Hash table,大的結果集計算hash value。
下面是圖:
Nested Join:
Merge
Hash Join