Oracle 多表連線的三種方式解讀

2021-07-25 11:31:55 字數 2527 閱讀 8762

在多表聯合查詢的時候,如果我們檢視它的執行計畫,就會發現裡面有多表之間的連線方式。

下面是從10053事件中擷取的部分trace原檔案。

join

order[2]: t[t]#1 t1[t1]#0

........省略

nl join

........

best nl cost: 574.45

resc: 574.45 resc_io: 567.00 resc_cpu: 213015937

resp: 574.45 resp_io: 567.00 resc_cpu: 213015937

..........省略

sm join

sm cost: 10.08

resc: 10.08 resc_io: 9.00 resc_cpu: 30818220

resp: 10.08 resp_io: 9.00 resp_cpu: 30818220

..........省略

ha join

ha cost: 9.10

resc: 9.10 resc_io: 9.00 resc_cpu: 2810323

resp: 9.10 resp_io: 9.00 resp_cpu: 2810323

join

order aborted: cost > best plan cost

***********************

可以發現多表之間的連線方式有三種連線方式nl join 、 sm join、 ha join。

對應nested loops,hash join 和 sort merge join.

對於被連線的資料子集較小的情況,巢狀迴圈連線是個較好的選擇。

在巢狀迴圈中,內錶被外表驅動,外表返回的每一行都要在內表中檢索找到與它匹配的行,因此整個查詢返回的結果集不能太大(大於1 萬不適合),要把返回子集較小表的作為外表(cbo 預設外表是驅動表),而且在內表的連線欄位上一定要有索引。當然也可以用ordered 提示來改變cbo預設的驅動表,

使用use_nl(table_name1 table_name2)可是強制cbo 執行巢狀迴圈連線。

nested loop一般用在連線的表中有索引,並且索引選擇性較好的時候.

步驟:確定乙個驅動表(outer table),另乙個表為inner table,驅動表中的每一行與inner表中的相應記錄join。類似乙個巢狀的迴圈。

適用於驅動表的記錄集比較小(<10000)而且inner表需要有有效的訪問方法(index)。

需要注意的是:join的順序很重要,驅動表的記錄集一定要小,返回結果集的響應時間是最快的。

通常情況下雜湊連線的效果都比排序合併連線要好,然而如果行源已經被排過序,在執行排序合併連線時不需要再排序了,這時排序合併連線的效能會優於雜湊連線。

可以使用use_merge(table_name1 table_name2)來強制使用排序合併連線.

sort merge join 用在沒有索引,並且資料已經排序的情況.

步驟:將兩個表排序,然後將兩個表合併。

通常情況下,只有在以下情況發生時,才會使用此種join方式:

雜湊連線(hash join )是cbo 做大資料集連線時的常用方式,優化器使用兩個表中較小的表(或資料來源)利用連線鍵在記憶體中建立雜湊表,然後掃瞄較大的表並探測雜湊表,找出與雜湊表匹配的行。

這種方式適用於較小的表完全可以放於記憶體中的情況,這樣總成本就是訪問兩個表的成本之和。但是在表很大的情況下並不能完全放入記憶體,這時優化器會將它分割成若干不同的分割槽,不能放入記憶體的部分就把該分割槽寫入磁碟的臨時段,此時要有較大的臨時段從而盡量提高i/o 的效能。

也可以用use_hash(table_name1 table_name2)提示來強制使用雜湊連線.

hash join用在兩個表的資料量差別很大的時候.

步驟:將兩個表中較小的乙個在記憶體中構造乙個hash表(對join key),掃瞄另乙個表,同樣對join key進行hash後探測是否可以join。適用於記錄集比較大的情況。

需要注意的是:如果hash錶太大,無法一次構造在記憶體中,則分成若干個partition,寫入磁碟的temporary segment,則會多乙個寫的代價,會降低效率。

hash join的工作方式是將乙個表(通常是小一點的那個表)做hash運算,將列資料儲存到hash列表中,從另乙個表中抽取記錄,做hash運算,到hash 列表中找到相應的值,做匹配。

nested loops 工作方式是從一張表中讀取資料,訪問另一張表(通常是索引)來做匹配,nested loops適用的場合是當乙個關聯表比較小的時候,效率會更高。

merge join 是先將關聯表的關聯列各自做排序,然後從各自的排序表中抽取資料,到另乙個排序表中做匹配,因為merge join需要做更多的排序,所以消耗的資源更多。 通常來講,能夠使用merge join的地方,hash join都可以發揮更好的效能。

oracle三種表連線方式

nested loop 對於被連線的資料子集較小的情況,nested loop連線是個較好的選擇。nested loop就是掃瞄乙個表,每讀到一條記錄,就根據索引去另乙個表裡面查詢,沒有索引一般就不會是 nested loops。一般在nested loop中,驅動表滿足條件結果集不大,被驅動表的連...

oracle 三種表連線方式

oracle 小知識 1.oracle 檢視表大小 select sum t.bytes 1024 1024 1024 from dba segments t where t.segment name tt tsfr fuzzy abnormal 2.強制走全表掃瞄和索引 full tt conve...

redis三種連線方式

tar zxvf redis 2.8.9.tar.gz cd redis 2.8.9 直接make 編譯 make 可使用root使用者執行 make install 將可執行檔案拷貝到 usr local bin目錄下。這樣就可以直接敲名字執行程式了。make install 加上 號使redis...