執行計劃的步驟
執行計劃的每一步傳回一組行,它們或為下一步所使用,或在最後一步時傳回發出SQL語句的使用者或應用程式。由每一步傳回的一組行叫做行源(row source)。圖5-1樹狀圖顯示了從一步到另一步行資料的流動。每個步驟的編號反映了在你觀察執行計劃時所示步驟的順序(如何觀察執行計劃將被簡短地說明)。一般來說這並不是每一步被執行的先後順序。執行計劃的每一步或從資料庫中擷取行,或接收來自一個或多個行來源的行資料作為輸入:
由紅色字框指出的步驟從資料庫中的資料檔案中物理檢索資料。這種步驟稱為存取路徑,後面會詳細介紹在Oracle可以使用的存取路徑:
步驟3步和第6步分別的從EMP表和SALGRADE表讀所有的行。
步驟5在PK_DEPTNO索引中找出由步驟3傳回的每個DEPTNO值。它找出與DEPT表中相關聯的那些行的ROWID。
步驟4步從DEPT表中檢索出ROWID為第5步傳回的那些行。
由黑色字框指出的步驟在行源上操作,如做2表之間的關聯,排序,或過濾等操作,後面也會給出詳細的介紹:
步驟一實現嵌套的循環操作(相當於C語句中的嵌套循環),接收從第3步和第4步來的行源,把來自第3步源的每一行與它第4步中對應的行連接在一起,返回結果行到第1步。
步驟_完成一個過濾器操作。它接收來自第2步和第6步的行源,消除掉第2步中來的,在第6步有相應行的那些行,並將來自第2步的剩下的行返回給發出語句的用戶或應用程式。
實作執行計劃步驟的順序
執行計畫中的步驟不是按照它們編號的順序來實現的:Oracle首先實現圖5-1樹結構圖形裡作為葉子出現的那些步驟(例如步驟3、5、6)。由每一步傳回的行稱為它下一步驟的行源。然後Oracle實現父步驟。
舉例來說,為了執行圖5-1的語句,Oracle以下列順序來實現這些步驟:
首先,Oracle實作步驟3,並一行一行地將結果行傳回第2步。
對第3步傳回的每一行,Oracle實現這些步驟:
-- Oracle實作步驟5,並將結果ROWID傳回給步驟4步。
-- Oracle實作步驟4,並將結果行傳回給步驟2步。
-- Oracle實作步驟2,將接受來自第3步的一行和來自第4步的一行,並返回
給第1步一行。
-- Oracle實作步驟6,如果有結果行的話,將它傳回給第1步。
-- Oracle實現步驟1,如果從步驟6返回行,Oracle將來自第2步的行傳回給
發出SQL語句的使用者。
注意Oracle對由步驟3步傳回的每一行實現步驟5,4,2,6一次。許多父步驟在它們能執行之前只需要來自它們子步驟的單一行。對這樣的父步驟來說,只要從子步驟已傳回單一行時立即實現父步驟(可能還有執行計畫的其餘部分)。如果該父步驟的父步驟同樣可以透過單一行返回啟動的話,那麼它也同樣被執行。所以,執行可以在樹上串聯上去,可能包含執行計畫的剩餘部分。對於這樣的操作,可以使用first_rows作為最佳化目標以便於實現快速回應使用者的請求。
對每個由子步驟依序檢索出來的每一行,Oracle就實現父步驟及所有串連在一起的步驟一次。對由子步驟返回的每一行所觸發的父步驟包括表訪問,索引訪問,嵌套的循環連接和過濾器。
有些父步驟在它們被實現之前需要來自子步驟的所有行。對這樣的父步驟,直到所有行從子步驟返回之前Oracle不能實現該父步驟。這樣的父步驟包括排序,排序一合併的連接,群組功能和總計。對於這樣的操作,不能使用first_rows作為最佳化目標,而可以用all_rows作為最佳化目標,使該中類型的操作耗費的資源最少。
有時語句執行時,並不是像上面說的那樣一步一步有先有後的進行,而是可能並行運行,如在實際環境中,3、5、4步可能並行運行,以便取得更好的效率。從上面的樹型圖上,是很難看出各個操作執行的先後順序,而透過ORACLE產生的另一種形式的執行計劃,則可以很容易的看出哪個操作先執行,哪個後執行,這樣的執行計劃是我們真正需要的,後面會給予詳細說明。
本文來自CSDN博客,轉載請標示出處:http: //blog.csdn.net/lcyhjx/archive/2009/12/20/5044799.aspx
-