1,先舉個例子:
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Byt
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | |
| 1 | SORT AGGREGATE | | 1 |
| 2 | TABLE ACCESS BY INDEX ROWID | T_TASK_G | 1 |
| 3 | INDEX RANGE SCAN | IX_TASK_SUP_S | 3 |
| 4 | VIEW | | 2 | 21
| 5 | COUNT STOPKEY | | |
| 6 | VIEW | | 2 | 21
| 7 | SORT ORDER BY | | 2 | 4
| 8 | NESTED LOOPS | | 2 | 4
| 9 | NESTED LOOPS | | 2 | 2
| 10 | TABLE ACCESS FULL | T_B_QU | 2 | 2
| 11 | INDEX UNIQUE SCAN | PK_T_B_ASSI | 1 |
| 12 | TABLE ACCESS BY INDEX ROWID| T_B_B | 1 |
| 13 | INDEX UNIQUE SCAN | PK_T_B_B | 1 |
--------------------------------------------------------------------------------
簡單來講,是從右到左,從上到下的原則。
從橫向來看10、11、13都是在最右端,優先 級是一樣的,這時候就需要看縱 向的。對于10和11的執 行順序,是先執行步驟10,再執行步驟11,步驟9結束後,再和步驟12得到的 結果集做步驟8的nested loop操作。
2,基礎概念
Card
是指計劃中這一步所 處理的行數。
Cost
是指cbo中這一步所 耗費的資源,以單塊讀 的IO成 本來表示。
Bytes
是指cbo中這一步所處理所 有記錄的位元組數,是估算出 來的一組值。
Predicate(謂詞)
一個查詢中的WHERE限制條件
Probed Table(被探查表)
該表又稱為内層表(INNER TABLE)。在我們從驅動表中得到具體 一行的資料後,在該表中尋找符合連接配接條件 的行。是以該表應當為 傳回較大row source的表且相應的列上應該有索引,索引掃描的範 圍越小,效率越高。
3,rowid
rowid是一個僞列,是系統自 己給加上的。對每個表都有一個rowid的僞列,但是表中并不實體存儲ROWID列的值。不過你可以像使用其它列 那樣使用它,但是不能删除該列,也不能對該列的值進行修改、插入。一旦一行資料插入資料庫,則rowid在該行的生命周期内是唯一的,即即使該行産生行遷移,行的rowid也不會改變。也有例外的情況,在分區表中,如果對分區列的值進行修改,這一行的資料會從一個分區遷移到另一個分區,那麼這行資料對應的rowid也會改變;表做shrink或者move的操作時,rowid也會改變。
rowid對通路一個表中的給定的行提供了最 快的通路方法,通過ROWID可以直接定位到相應的資料塊上,然後将其讀到記憶體。我們建立一個索引時,該索引不但存儲索引列的值,而且也存儲索引值所對應的行的ROWID,這樣我們通過索引快 速找到相應行的ROWID後,通過該ROWID,就可以迅速将 資料查詢出來。這也就是我們使用索引查詢時,速度比較快的原因。
在ORACLE 8以前的版本中,ROWID由FILE、BLOCK、ROW NUMBER構成。随着oracle8中對象概念的擴充,ROWID發生了變化,ROWID由OBJECT、FILE、BLOCK、ROW NUMBER構成。利用DBMS_ROWID可以将rowid分解成上述的 各部分,也可以将上述的各部分組成一個有效的rowid。
4,resuive sql
有時為了執行使用者發出的一個sql語句,Oracle必須 執行一些額外的語句,我們将這些額外的語句稱之為‘recursive calls’或‘recursive SQL statements’。比如建立一個表,ORACLE總是隐含的發出一些recursive SQL語句來修改資料字典資訊如tab$等。當需要的資料字典 資訊沒有在共享記憶體中時,經常會發生Recursive calls,這些Recursive calls會将數 據字典資訊從 硬碟讀入記憶體中。使用者不比關心這些recursive SQL語句的執行情況, ORACLE會自動的在内部執行這些語句。當然DML語句與SELECT、sql parse或者在執行過程中需要空間擴充都可能 引起recursive SQL。
5,row source
用在查詢中,由上一操作傳回的符合條件的行的集合,即可以是表的全部行資料的集合;也可以是表的部分行資料的集合;也可以為對上2個row source進行連接配接操作(如join連接配接)後得到的行資料集合。
6,driving table
該表又稱為外層表(OUTER TABLE)。這個概念用于嵌套與HASH連接配接中。如果該row source傳回較多的行資料,則對所有的後續操作有負面影響。一般說來,是應用查詢的限制條件後,傳回較少行源的表作為驅動表,是以如果一個大表在WHERE條件有有限制條件(如等值限制),則該大表作為驅動表也是合适的,是以并不是隻有較小的表可以作為驅動表,正确說法應該為應用查詢的限制條件後,傳回較少行源的表作為驅動表。在執行計劃中,應該為靠上的那個row source。
7,組合索引
組合索引就是由多個列構成的索引。在組合索引 中有一個重要的概念:引導列(leading column),建立組合索引 時最前面的列即為引導列。如
Create index idx_test on table_name(col1,col2,…);
當我們進行查詢時可以使用”where col1 = ? ”,也可以使用”where col1 = ? and col2 = ?”,這樣的限制條件都會使 用索引,但是”where col2 = ? ”查詢就不會使用該索引。是以限制條件中包含先導列時,該限制條件才會使用該組合索引。
有些情況下,”where col2 = ? ”也會使用索引 ,使用的是index skip scan,col1的distinct值有N個,那麼就相當于N個基于col2的查詢的union。N這個值越大,union的個數就越多,index skip scan的效率就越低,是以大部分情況下,當我們看到執 行計劃中出現index skip scan時,需要加以關注。
8,可選擇性
比較一下列中唯一鍵的數量和表中的行數,就可以判 斷該列的可選擇性。如果該列的唯一鍵的數量/表中的行數”的 比值越接近1,則該列的可選擇性越高,該列就越适合建立索引,同樣索引的可選擇性也越高。在可選擇性高 的列上進行查詢時,傳回的資料就較少,比 較适合使用索引查詢。