閱讀oracle執行計劃的方法:
先從最開頭一直往右看,直到看到最右邊的並列的地方,對於不併列的,靠右的先執行:對於並列的,靠上的先執行。
即並列的縮進塊,從上往下執行,非並列的縮進塊,從下往上執行。
如下示例:
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 NESTED LOOPS
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'TB_HOST_BATCH_DTL'
3 2 INDEX (RANGE SCAN) OF 'XIE2TB_HOST_BATCH_DTL' (NON-UNIQUE)
4 1 TABLE ACCESS (BY INDEX ROWID) OF 'TB_BATCH_TRAN_CTRL'
5 4 INDEX (UNIQUE SCAN) OF 'SYS_C0034652' (UNIQUE)
不妨假設最右邊的數據爲行號,語句執行是按塊進行的。
從上述執行計劃的開頭一直往右看,直到找到最右邊並列的。也就是從SELECT STATEMENT開始往右找。
找到一級縮進塊,只有一個,沒有優先級可言,如下:
1 0 NESTED LOOPS
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'TB_HOST_BATCH_DTL'
3 2 INDEX (RANGE SCAN) OF 'XIE2TB_HOST_BATCH_DTL' (NON-UNIQUE)
4 1 TABLE ACCESS (BY INDEX ROWID) OF 'TB_BATCH_TRAN_CTRL'
5 4 INDEX (UNIQUE SCAN) OF 'SYS_C0034652' (UNIQUE)
再在一級縮進塊中找二級縮進塊,找到兩個,如下:
第一個二級縮進塊:
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'TB_HOST_BATCH_DTL'
3 2 INDEX (RANGE SCAN) OF 'XIE2TB_HOST_BATCH_DTL' (NON-UNIQUE)
第二個二級縮進塊:
4 1 TABLE ACCESS (BY INDEX ROWID) OF 'TB_BATCH_TRAN_CTRL'
5 4 INDEX (UNIQUE SCAN) OF 'SYS_C0034652' (UNIQUE)
按照並列塊從上往下執行的原則,第一個二級縮進塊的所有語句將優先於第二個二級縮進塊的語句執行。
而兩個二級縮進塊執行完,才能執行一級縮進塊,這是因爲非並列的縮進塊,從下往上執行。
再在二級縮進塊中找三級縮進塊。
第一個二級縮進塊中只有一個三級縮進塊,如下:
3 2 INDEX (RANGE SCAN) OF 'XIE2TB_HOST_BATCH_DTL' (NON-UNIQUE)
由於沒有更低層級的縮進塊,因此,該塊最先執行。然後執行二級縮進塊。
第二個二級縮進塊中也只有一個三級縮進塊,如下:
5 4 INDEX (UNIQUE SCAN) OF 'SYS_C0034652' (UNIQUE)
二級縮進塊中沒有更低層次的縮進塊了,因此,執行完第一個二級縮進塊的所有語句後,便執行此三級縮進塊,再執行對應的二級縮進塊。
兩個二級縮進塊均執行完成後,再執行整個一級縮進塊。
因此,若按行排序,語句的執行順序便是: 3 -> 2 -> 5 -> 4 -> 1, 即:
3 2 INDEX (RANGE SCAN) OF 'XIE2TB_HOST_BATCH_DTL' (NON-UNIQUE) ->
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'TB_HOST_BATCH_DTL' ->
5 4 INDEX (UNIQUE SCAN) OF 'SYS_C0034652' (UNIQUE) ->
4 1 TABLE ACCESS (BY INDEX ROWID) OF 'TB_BATCH_TRAN_CTRL' ->
1 0 NESTED LOOPS
執行計劃順序的理論解釋:
執行計劃是按一定規則顯示的,如下:
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 NESTED LOOPS
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'TB_HOST_BATCH_DTL'
3 2 INDEX (RANGE SCAN) OF 'XIE2TB_HOST_BATCH_DTL' (NON-UNIQUE)
4 1 TABLE ACCESS (BY INDEX ROWID) OF 'TB_BATCH_TRAN_CTRL'
5 4 INDEX (UNIQUE SCAN) OF 'SYS_C0034652' (UNIQUE)
第一個列是步驟的ID (相當於我們說的行號)
第二個列是父步驟的ID
第三個列是該步驟要進行的操作。
在執行過程中,父步驟依賴於子步驟。只有對應的所有子步驟執行完,才能執行父步驟。
因此,步驟0的子步驟爲1, 步驟1的子步驟爲2,4, 步驟2子步驟爲3,步驟4的子步驟爲5, 步驟3,5沒有子步驟了。
故步驟3所在的模塊,或步驟5所在的模塊先執行。但步驟3排在步驟5的前面,故步驟3所在的模塊先執行。因此,順序仍是:
3 -> 2 -> 5 -> 4 -> 1