1. 程式人生 > >oracle執行計劃相關

oracle執行計劃相關

執行計劃相關

根據Operation縮排來判斷,縮排最多的最先執行;(縮排相同時,最上面的最先執行)

同一級如果某個動作沒有子ID就最先執行

同一級的動作執行時遵循最上最右先執行的原則

TABLE ACCESS BY … 即描述的是該動作執行時表訪問(或者說Oracle訪問資料)的方式;

表訪問的幾種方式:(非全部)

TABLE ACCESS FULL(全表掃描)

TABLE ACCESS BY ROWID(通過ROWID的表存取)

TABLE ACCESS BY INDEX SCAN(索引掃描)

索引掃描又分五種:

INDEX UNIQUE SCAN(索引唯一掃描)

INDEX RANGE SCAN(索引範圍掃描)

INDEX FULL SCAN(索引全掃描)

INDEX FAST FULL SCAN(索引快速掃描)

INDEX SKIP SCAN(索引跳躍掃描)

INDEX UNIQUE SCAN(索引唯一掃描):

針對唯一性索引(UNIQUE INDEX)的掃描,每次至多隻返回一條記錄;

表中某欄位存在 UNIQUE、PRIMARY KEY 約束時,Oracle常實現唯一性掃描;

INDEX RANGE SCAN(索引範圍掃描):

使用一個索引存取多行資料;

發生索引範圍掃描的三種情況:

在唯一索引列上使用了範圍操作符(如:> < <> >= <= between)

在組合索引上,只使用部分列進行查詢(查詢時必須包含前導列,否則會走全表掃描)

對非唯一索引列上進行的任何查詢

c) INDEX FULL SCAN(索引全掃描):

進行全索引掃描時,查詢出的資料都必須從索引中可以直接得到(注意全索引掃描只有在CBO模式下才有效)

d) INDEX FAST FULL SCAN(索引快速掃描):

掃描索引中的所有的資料塊,與 INDEX FULL SCAN 類似,但是一個顯著的區別是它不對查詢出的資料進行排序(即資料不是以排序順序被返回)

e) INDEX SKIP SCAN(索引跳躍掃描):

Oracle 9i後提供,有時候複合索引的前導列(索引包含的第一列)沒有在查詢語句中出現,oralce也會使用該複合索引,這時候就使用的INDEX SKIP SCAN;

CBO:

CBO是一種比RBO更加合理、可靠的優化器,在ORACLE 10g中完全取代RBO;

CBO通過計算各種可能的執行計劃的“代價”,即COST,從中選用COST最低的執行方案作為實際執行方案;

它依賴資料庫物件的統計資訊,統計資訊的準確與否會影響CBO做出最優的選擇,也就是對資料“敏感”。

NESTED LOOPS … 描述的是表連線方式;

JOIN 關鍵字用於將兩張表作連線,一次只能連線兩張表,JOIN 操作的各步驟一般是序列的(在讀取做連線的兩張表的資料時可以並行讀取);

表(row source)之間的連線順序對於查詢效率有很大的影響,對首先存取的表(驅動表)先應用某些限制條件(Where過濾條件)以得到一個較小的row source,可以使得連線效率提高。

驅動表(Driving Table):

表連線時首先存取的表,又稱外層表(Outer Table),這個概念用於 NESTED LOOPS(巢狀迴圈) 與 HASH JOIN(雜湊連線)中;

如果驅動表返回較多的行資料,則對所有的後續操作有負面影響,故一般選擇小表(應用Where限制條件後返回較少行數的表)作為驅動表。

匹配表(Probed Table):

又稱為內層表(Inner Table),從驅動表獲取一行具體資料後,會到該表中尋找符合連線條件的行。故該表一般為大表(應用Where限制條件後返回較多行數的表)。

表連線的幾種方式:

SORT MERGE JOIN(排序-合併連線)

NESTED LOOPS(巢狀迴圈)

HASH JOIN(雜湊連線)

CARTESIAN PRODUCT(笛卡爾積)

SORT MERGE JOIN(排序-合併連線):

假設有查詢:select a.name, b.name from table_A a join table_B b on (a.id = b.id)

內部連線過程:

a) 生成 row source 1 需要的資料,按照連線操作關聯列(如示例中的a.id)對這些資料進行排序

b) 生成 row source 2 需要的資料,按照與 a) 中對應的連線操作關聯列(b.id)對資料進行排序

c) 兩邊已排序的行放在一起執行合併操作(對兩邊的資料集進行掃描並判斷是否連線)

NESTED LOOPS(巢狀迴圈):

內部連線過程:

a) 取出 row source 1 的 row 1(第一行資料),遍歷 row source 2 的所有行並檢查是否有匹配的,取出匹配的行放入結果集中

b) 取出 row source 1 的 row 2(第二行資料),遍歷 row source 2 的所有行並檢查是否有匹配的,取出匹配的行放入結果集中

c) ……

若 row source 1 (即驅動表)中返回了 N 行資料,則 row source 2 也相應的會被全表遍歷 N 次。

因為 row source 1 的每一行都會去匹配 row source 2 的所有行,所以當 row source 1 返回的行數儘可能少並且能高效訪問 row source 2(如建立適當的索引)時,效率較高。

應儘可能使用限制條件(Where過濾條件)使驅動表(row source 1)返回的行數儘可能少,同時在匹配表(row source 2)的連線操作關聯列上建立唯一索引(UNIQUE INDEX)或是選擇性較好的非唯一索引,此時巢狀迴圈連線的執行效率會變得很高。若驅動表返回的行數較多,即使匹配表連線操作關聯列上存在索引,連線效率也不會很高。

HASH JOIN(雜湊連線) :

雜湊連線只適用於等值連線(即連線條件為 = )

HASH JOIN對兩個表做連線時並不一定是都進行全表掃描,其並不限制表訪問方式;

內部連線過程簡述:

a) 取出 row source 1(驅動表,在HASH JOIN中又稱為Build Table) 的資料集,然後將其構建成記憶體中的一個 Hash Table(Hash函式的Hash KEY就是連線操作關聯列),建立Hash點陣圖(bitmap)

b) 取出 row source 2(匹配表)的資料集,對其中的每一條資料的連線操作關聯列使用相同的Hash函式並找到對應的 a) 裡的資料在 Hash Table 中的位置,在該位置上檢查能否找到匹配的資料