qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請訪問 http://qaseven.github.io/

          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ù)庫

          <2013年12月>
          24252627282930
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          導航

          統(tǒng)計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 潼关县| 乌拉特中旗| 大渡口区| 凯里市| 无棣县| 保亭| 萍乡市| 维西| 墨竹工卡县| 潜山县| 昆明市| 肃南| 玉树县| 中阳县| 蛟河市| 沂源县| 敦化市| 都昌县| 建平县| 柳河县| 赤峰市| 隆子县| 白水县| 荔浦县| 德兴市| 东乡族自治县| 察隅县| 莱芜市| 桃园市| 威远县| 获嘉县| 连山| 泸州市| 丽江市| 玛沁县| 海城市| 上饶县| 威海市| 邛崃市| 温宿县| 拉萨市|