ORACLE數(shù)據(jù)庫SQL語句的執(zhí)行過程
SQL語句在數(shù)據(jù)庫中處理過程是怎樣的呢?執(zhí)行順序呢?在回答這個問題前,我們先來回顧一下:在ORACLE數(shù)據(jù)庫架構(gòu)下,SQL語句由用戶進程產(chǎn)生,然后傳到相對應(yīng)的服務(wù)端進程,之后由服務(wù)器進程執(zhí)行該SQL語句,如果是SELECT語句,服務(wù)器進程還需要將執(zhí)行結(jié)果回傳給用戶進程。
SQL語句的執(zhí)行過程一般如下:
解析(PARSE)—— 綁定(BIND)——執(zhí)行(EXECUTE)——提取(FETCH 只有SELECT才需要這步)
解析
服務(wù)器進程接收到一個SQL語句時,首先要將其轉(zhuǎn)換成執(zhí)行這個SQL語句的最有效步驟,這些步驟被稱為執(zhí)行計劃。
Step 1:檢查共享池中是否有之前解析相同的SQL語句后所存儲的SQL文本、解析樹和執(zhí)行計劃。如果能從共享池的緩存庫中找到之前解析過生成的執(zhí)行計劃,則SQL語句則不需要再次解析,便可以直接由庫緩存得到之前所產(chǎn)生的執(zhí)行計劃,從而直接跳到綁定或執(zhí)行階段,這種解析稱作軟解析。
但是如果在共享池的庫緩存中找不到對應(yīng)的執(zhí)行計劃,則必須繼續(xù)解析SQL、生成執(zhí)行計劃,這種解析稱作硬解析
在緩存池解析過的SQL,會有一個對應(yīng)的哈希值與之對應(yīng),你可以通過V$SQL視圖來查詢,請看下面一個例子:
SQL>SELECT * FROM SCOTT.DEPT WHERE DEPTNO =10; SQL>SELECT * FROM SCOTT.DEPT WHERE DEPTNO =20; SQL> SELECT HASH_VALUE , ADDRESS, EXECUTIONS ,SQL_TEXT FROM V$SQL WHERE SQL_TEXT LIKE 'SELECT * FROM SCOTT.DEPT WHERE DEPTNO%' ; HASH_VALUE ADDRESS EXECUTIONS SQL_TEXT ---------- -------- ---------- -------------------------------------------------------------------------------- 442836625 27EE4B7C 1 SELECT * FROM SCOTT.DEPT WHERE DEPTNO =20 4215405494 27EEA3BC 1 SELECT * FROM SCOTT.DEPT WHERE DEPTNO =10 |
下面我們先清空共享池緩存的執(zhí)行計劃,然后使用綁定變量,查看執(zhí)行計劃的變換
SQL> ALTER SYSTEM FLUSH SHARED_POOL; System altered SQL> VARIABLE deptno NUMBER; SQL> EXECUTE :deptno := 10; PL/SQL procedure successfully completed deptno --------- 10 SQL> SELECT * FROM SCOTT.DEPT WHERE DEPTNO=:deptno; DEPTNO DNAME LOC ------ -------------- ------------- 10 ACCOUNTING NEW YORK SQL> EXECUTE :deptno :=20; PL/SQL procedure successfully completed deptno --------- 20 SQL> SELECT * FROM SCOTT.DEPT WHERE DEPTNO=:deptno; DEPTNO DNAME LOC ------ -------------- ------------- 20 RESEARCH DALLAS SQL> SELECT HASH_VALUE , ADDRESS, EXECUTIONS ,SQL_TEXT 2 FROM V$SQL 3 WHERE SQL_TEXT LIKE ' SELECT * FROM SCOTT.DEPT WHERE DEPTNO%'; HASH_VALUE ADDRESS EXECUTIONS SQL_TEXT ---------- -------- ---------- -------------------------------------------------------------------------------- 3669302979 27D2BA1C 2 SELECT * FROM SCOTT.DEPT WHERE DEPTNO=:deptno |
Step 2:語法分析,分析SQL語句的語法是否符合規(guī)范,衡量語句中各表達式的意義
Step 3:檢查是否存在語義錯誤和權(quán)限。語義分析,檢查語句中設(shè)計的所有數(shù)據(jù)庫對象是否存在,且用戶有相應(yīng)的權(quán)限。
Step 4:視圖轉(zhuǎn)換和表達式轉(zhuǎn)換 將涉及視圖的查詢語句轉(zhuǎn)換為相應(yīng)的對基表查詢語句。將復(fù)雜表達式轉(zhuǎn)化較為簡單的等效連接表達式。
Step 5:決定最佳執(zhí)行計劃。優(yōu)化器會生成多個執(zhí)行計劃,在按統(tǒng)計信息帶入,找出執(zhí)行成本最小的執(zhí)行計劃,作為執(zhí)行此SQL語句的執(zhí)行計劃
Step 6:將SQL文本、解析樹、執(zhí)行計劃緩存到庫緩存,存放地址以及SQL語句的哈希值。
綁定
如果SQL語句中使用了綁定變量,掃描綁定變量的聲明,給綁定變量賦值。則此時將變量值帶入執(zhí)行計劃。
執(zhí)行
此階段按照執(zhí)行計劃執(zhí)行SQL,產(chǎn)生執(zhí)行結(jié)果。不同類型的SQL語句,執(zhí)行過程也不同。
SELECT查詢
檢查所需的數(shù)據(jù)塊是否已經(jīng)在緩沖區(qū)緩存中,如果已經(jīng)在緩沖區(qū)緩存中,直接讀取器內(nèi)容即可。這種讀取方式稱為邏輯讀取。如果所需數(shù)據(jù)不在緩沖區(qū)緩存中,則服務(wù)器進程需要先掃描數(shù)據(jù)塊,讀取相應(yīng)數(shù)據(jù)塊到緩沖區(qū)緩存,這種讀取方式稱為物理讀。和邏輯讀相比較,它更加耗費CPU和IO資源。
修改操作(INSERT、UPDATE、DELETE)
Step 1:檢查所需的數(shù)據(jù)庫是否已經(jīng)被讀取到緩沖區(qū)緩存中。如果已經(jīng)存在緩沖區(qū)緩存,則執(zhí)行Step 3
Step 2:若所需的數(shù)據(jù)庫并不在緩沖區(qū)緩存中,則服務(wù)器將數(shù)據(jù)塊從數(shù)據(jù)文件讀取到緩沖區(qū)緩存中
Step 3:對想要修改的表取得的數(shù)據(jù)行鎖定(Row Exclusive Lock),之后對所需要修改的數(shù)據(jù)行取得獨占鎖
Step 4:將撤銷數(shù)據(jù)的Redo記錄復(fù)制到日志緩沖區(qū),產(chǎn)生數(shù)據(jù)行的撤銷數(shù)據(jù),將數(shù)據(jù)行修改的Redo記錄復(fù)制到日志緩沖區(qū),修改數(shù)據(jù)行。
Step 5: 產(chǎn)生數(shù)據(jù)修改的撤銷數(shù)據(jù)
Step 6:復(fù)制數(shù)據(jù)修改的Redo記錄到日志緩沖區(qū)
Step 7:修改數(shù)據(jù)行的內(nèi)容,如果之前的緩沖為干凈緩沖,則此時將變?yōu)榕K緩沖。
提取
提取只有SELECT查詢語句才有的步驟。獲取查詢的記錄行,必要的時候?qū)Σ樵兘Y(jié)果排序。
posted on 2013-12-09 10:34 順其自然EVO 閱讀(353) 評論(0) 編輯 收藏 所屬分類: 數(shù)據(jù)庫