Oracle表連線之巢狀迴圈

2021-08-27 06:33:59 字數 1455 閱讀 4521

在資料庫系統中執行乙個查詢sql語句,如果這個查詢只操作一張表,那麼僅僅涉及到這個表及關聯物件的訪問。訪問方式通常是三種:全表掃瞄、全索引掃瞄和索引掃瞄。

如果這個查詢操作兩張及以上的表,那麼需要操作的表之間的連線關係就變得至關重要。

資料庫系統執行該sql時,永遠都是兩個結果集關聯。

例如,操作三張表,那麼就是其中兩張表關聯出乙個結果集,和第三張表關聯。

操作四張表,那麼就是其中兩張表關聯出乙個結果集,和第三張表關聯出乙個結果集,再和第四張表關聯出最後的結果集。當然也可能是兩兩關聯出兩個結果集,再相互關聯得到最後的結果集。

操作5張表,各個表之間的關聯方式就更複雜了。

這些描述就是資料庫系統用來根據操作表的不同排列和組合而生成不同的執行計畫。

oracle資料庫系統會使用一種機制,來決定哪一種組合效能最好。這種機制稱為基於成本的優化器(cost-based optimization,簡稱為cbo)。

因為操作多表時,都會按照兩表關聯操作,最終得出需要的結果集。

oracle資料庫系統將兩表關聯方式主要分為三種。

這裡介紹一下巢狀迴圈 (nested  loops 簡稱nl) 的連線方式。

巢狀迴圈,顧名思義就是將乙個表為出發點,將該錶全部記錄逐條去遍歷另外一張表的記錄,符合條件的就是寫入結果集。

例如:select a.*, b *

from emp a, dept b

where a.deptno = b.deptno;

如使用emp表為出發點,將emp表的記錄都查詢出來為m條,再將這m條記錄的字段deptno值,逐條和dept表的所有記錄的deptno字段值匹配,假如dept表有n條記錄。

匹配出來的記錄符合條件就寫入到結果集中。

那麼這樣關聯操作過程中,操作的記錄條數就是:先是emp表的m條,接著是dept表n條,但查了m遍,總的記錄數就是m+m*n。

如使用dept表為出發點,去遍歷emp表,那麼總的記錄數就是n+n*m。

出發點不同的連線方法,需要的成本就是不一樣的。cbo會去最小的那個。

這裡作為出發點的表,官方術語將其稱為外部表,也叫驅動表。

使用偽**來表示一下巢狀迴圈連線

declare

begin

for outer_table in (select * from emp) loop

for inner_table in (select *

from dept                       

where deptno = outer_table.deptno) loop

dbms_output.put_line(inner_table.*, outer_table.*);

end loop;

end loop;

end;

基於巢狀連線的特點,我們可以想得到,它在兩個關聯表的資料量相差比較大時採用,但整體上資料量都不應該太大。該關聯方式適用於得到小資料量的查詢操作。

Oracle 巢狀迴圈 雜湊連線

假設我們現在有一條語句,執行的時間需要半個小時,即使我們僅僅需要知道該語句的執行計畫,此種情況下,我們必須等待半個小時。因此,如果查詢的效能很慢,我們可以選擇選擇使用explain plan for select from table dbms xplan.display 命令。select use...

巢狀迴圈連線 Nested Loops Join

巢狀迴圈連線 nested loops join 是一種兩個表在做表連線時依靠兩層巢狀迴圈 分別為外層迴圈和記憶體迴圈 來得到連線結果集的表連線方法。即外層迴圈對應的驅動結果集有多少條記錄,遍歷被驅動表的內層迴圈就要做多少次 這就是所謂的 巢狀迴圈 的含義。對於巢狀迴圈連線的優缺點及適用場景如下 a...

Mysql巢狀迴圈連線演算法

迴圈連線演算法分為兩種 1.巢狀迴圈連線演算法 2.塊巢狀迴圈連線演算法乙個簡單的巢狀迴圈連線 nlj 演算法從乙個迴圈中的第乙個表中讀取一行中的行,將每行傳遞給巢狀迴圈,以處理連線中的下乙個表。該過程重複多次,因為還有待連線的表。假設三個表之間的連線 t1,t2以及 t3,那麼nlj演算法會這麼來...