天天看點

Oracle一個SQL語句的處理過程(轉)

Statement

 Submitted

 |

 Is it in an open cursor?--------------YES----V  

 |                                                                         | 

 NO                                                                    |  

 |                                            |

 Is SESSION_CACHED_CURSORS = Value            | 

 and cursor in           --------------YES----V   In these 3 cases we 

 Session Cursor cache?                        |   know that the cursor has

 |                                            |   already been parsed, so

 NO                                           |   re-parsing is

 |                                            |   unnecessary.

 Is HOLD_CURSOR=Y                             |

 and cursor in           --------------YES----V     

 Held cursor cache?                           |      

 |                                            |      

 NO                                           |       

 |                                            |              ^

 OPEN A CURSOR                                |  CLIENT SIDE |      

 |                                            | -------------|

 Statement is Hashed and compared             |  SERVER SIDE |

 with the Hashed value in the sql area        |              V

 |                                            V

 Is it in sql area? --YES-(Soft Parse)--&gt ---------

 |                                       |         |

 NO                                      | EXECUTE |

 |                                       |         |

 PARSE STATEMENT ('Hard' Parse)---------&gt ---------------------------------

對照metalink給出的這個示意圖,我們可以對SQL的處理過程作如下的描述:

1、檢查是否有打開的遊标,如果有,則直接通過遊标link到位于PGA的private SQL AREA( private SQL area),轉步驟11。否則,執行步驟2。

2、檢查初始化參數SESSION_CACHED_CURSORS是否被設定,如果被設定,則同樣可以通過遊标指向到位于PGA的私有SQL AREA,轉步驟11。否則執行步驟3。

3、檢查HOLD_CURSOR以及RELEASE_CURSOR的設定。如果RELEASE_CURSOR=no(預設no),HOLD_CURSOR=yes(預設為no),當ORACLE執行完SQL語句,為private SQL AREA配置設定的記憶體空間被保留,cursor和private SQL AREA之間的link也被保留,預編譯程式不再使用它,同樣可以通過這個指針直接在private SQL AREA獲得語句,轉步驟11。

    這上面的三種情況,實際上都沒有作任何parse,都是直接從位于PGA中的private SQL AREA獲得語句并直接執行。此為fast parse。

    這三種情況都不存在的情況下,oracle轉到步驟4執行。

4、建立一個遊标。

5、文法檢查Syntax Check:檢查文法書寫是否正确,是否符合SQL Reference Manual中給出的SQL文法。

6、語義分析Semantic Analysis:查找資料字典,檢查表、列是否正确,在所要求的對象上擷取文法分析鎖,使得在語句的文法分析過程中不改變這些對象的定義, 驗證為存取所涉及的模式對象所需的權限是否滿足。

7、将語句轉化成ASCII等效數字碼,再通過雜湊演算法得到散列值。

8、檢查庫緩存中是否存在同樣hash值的語句。如果存在,轉步驟11。否則,執行步驟9。 這就是soft parse。

9、選擇執行計劃。從可用的執行計劃中選擇一個最優的執行計劃,其中包括存儲大綱(srored outline)或物化視圖(materialized view)相關的決定。

10、生成該語句的一個編譯代碼(p-code)。

11、執行語句。

cursor:from Oracle9i Database Concepts:A cursor is a handle or name for a private SQL area--an area in memory in which a parsed statement and other information for processing the statement are kept.

當某個session執行一條語句之後,該語句的parse結果會在library cache中儲存,同時也會在PGA的private sql area有一個拷貝的副本。cursor 總是通過一個link是直接鍊到 private sql area的。如果在private中沒有找到這個副本,就需要對SQL進行parse,然後再在library cache中進行hash值的比對。是以總的來說,使用cursor能不需要任何parse,就是因為直接從目前的private sql area中得到了語句相關資訊,包括執行計劃。而一旦需要到library cache中進行比對,就必須需要parse。

soft parse不是不作parse,隻是parse的量比較小,隻需要作文法檢查和語義分析,以及散列語句。

關于預編譯的兩個參數說明:

HOLD_CURSOR

    HOLD_CURSOR預設值為no,當oracle執行完sql語句,close遊标之後,預編譯程式将遊标和緩存SQL的cache連結标記為可重用。并且釋放已經配置設定給該語句的私有SQL AREA記憶體區域,解除parse locks。當有下一個語句需要使用時,這個連結立即被重用。

    當HOLD_CURSOR=YES時,當oracle執行完sql語句,為private SQL AREA配置設定的記憶體空間被保留,cursor和private SQL AREA之間的link也被保留,預編譯程式不再使用它。

RELEASE_CURSOR

    RELEASE_CURSOR的優先級高于HOLD_CURSOR。RELEASE_CURSOR預設值為no。RELEASE_CURSOR=yes,當oracle執行完sql語句,close遊标之後,緩存被釋放,鎖被解除,連結被辨別為可重用。RELEASE_CURSOR=no,則主要有HOLD_CURSOR來決定了。

    另外說明一點,這兩個參數是在預編譯的檔案中定義的。

這部分内容詳細見:

oracle documents -> Programmer's Guide to the Oracle Precompilers -> Performance Tuning

   ->  Optimizing SQL Statements  -> Using the Cursor Management Options

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12801008/viewspace-607457/,如需轉載,請注明出處,否則将追究法律責任。

轉載于:http://blog.itpub.net/12801008/viewspace-607457/