從連線到資料(二)

realkid4發表於2011-01-03

Client與Server Process建立了連線,構成一次會話session之後。客戶端就可以輸入SQL語句,對資料庫資料進行操作了。

 

2、解析SQL,執行操作

 

SQL語句是描述性語句。我們使用SQL的時候,只是去描述我們需要資料的特徵,而不是確定資料獲取的執行方法。

 

任何一條SQL語句執行,都是透過解析、執行和獲取三個主要步驟,若干個子步驟組成。

 

解析parse

 

任何SQL語句,在Oracle環境下都是處理為遊標cursor。對SQL語句的處理,實際上就是對cursor的處理。

 

Oracle處理SQL語句,首先要檢查SGA區中的shared pool子區,看裡面是否存在相同SQL的父遊標子游標。查詢的依據,就是SQL語句本身(以及其hash值)。

 

每一個在Oracle中執行的SQL語句,都需要在shared pool中建立一個父遊標和子游標的對。父遊標對應的是所有相同SQL語句的遊標,都可以共享該父遊標。在同一個父遊標下,允許有多個子遊標,他們表示SQL語句在不同執行使用者、不同最佳化器模式和環境等因素下,對應的不同的執行計劃。

 

SQL在Share Pool中尋找的共享Cursor,就是尋找相同的子游標項,目的是為了共用執行計劃。

 

Oracle中,可以透過v$sqlarea和V$sql兩個檢視,分別檢視shared pool中的父子游標。

 

//命令列中先執行該語句

SQL> select * from t;

 

//檢視父遊標

SQL> select sql_text from v$sqlarea where sql_text like 'select * from t%';

 

SQL_TEXT

-----------------------------

select * from t

 

//檢視子游標

SQL> select sql_text from v$sql where sql_text like 'select * from t%';

 

SQL_TEXT

-------------------------------

select * from t

 

一個父遊標下,是可以對應多條子游標記錄的。v$sqlarea檢視中,有一列version_count表示該父遊標有多少子游標對應共享記錄。v$sql中也有對應標誌執行版本的列。

 

一條SQL語句,透過語法檢查後。如果可以在shared pool中尋找到可共享的子游標物件,就可以實現執行計劃的共享。這個過程,我們稱為軟解析。

 

 

如果沒有在shared pool中尋找到相同可共享的遊標記錄。那麼,首先向例項申請,要求SGA中分配空間和資源,進行SQL語句的分析解析工作。這部分通常需要分配記憶體空間,以裝載生成的父子游標記錄。我們稱這個過程為硬解析。

 

 

相對於軟解析,硬解析需要消耗更多的系統資源。更重要的是,在進行硬解析的過程中,對SQL涉及到的資料庫物件,可能都有鎖或者latch的操作。這樣是不利於實現多使用者併發的資料庫系統的。所以,一般我們都儘量避免硬解析,儘可能實現遊標共享。

 

當然,軟解析也不是絕對完美的選擇。在一些高併發、高處理量的系統中,絕對的遊標共享也是可能引起效能瓶頸的。所以,一些時候還要人為避免軟解析的發生。

 

 

實現遊標共享的最常用技術就是繫結變數,透過繫結變數,可以實現類似業務操作SQL的共享。也就是一種軟解析技術。但是,繫結變數最大的問題也就是peeking,在實際系統中,也是要仔細區別斟酌的。

 

 

SQL語句的解析後,Oracle要使用最佳化器生成對應的執行計劃。目前,最常用的就是CBO(基於成本的最佳化器)。最佳化器的原理比較複雜,是Oracle核心技術之一。簡單的說,Oracle會用不同的方法(自動收集、作業指令碼),收集資料表、索引的統計資訊,作為CBO工作的依據。之後,對一個SQL,Oracle會制定出多種執行路徑方法,分別計算每個路徑方法的執行成本(估算),最後確定成本最低的執行計劃作為實際執行計劃。

 

一旦一條SQL的執行計劃確定之後,shared pool裡的遊標記錄就和這個執行計劃連線起來。下次再有相同子游標的SQL,則直接使用這個執行計劃。

 

 

執行計劃

----------------------------------------------------------

Plan hash value: 47235625

 

---------------------------------------------------------------------------

| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |

---------------------------------------------------------------------------

|   0 | SELECT STATEMENT   |      |     1 |     4 |     3  (34)| 00:00:01 |

|   1 |  HASH GROUP BY     |      |     1 |     4 |     3  (34)| 00:00:01 |

|   2 |   TABLE ACCESS FULL| T    |     2 |     8 |     2   (0)| 00:00:01 |

---------------------------------------------------------------------------

 

 

 

上面是一段SQL語句的執行計劃。可以看出,執行計劃就是一系列的步驟,告訴Oracle執行引擎如何一步步的將結果集合返回。

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

相關文章