<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    lqxue

    常用鏈接

    統(tǒng)計

    book

    tools

    最新評論

    [收藏]sql 語句的執(zhí)行過程

    第1章 SQL語句處理的過程  在調(diào)整之前我們需要了解一些背景知識,只有知道這些背景知識,我們才能更好的去調(diào)整sql語句。
    本節(jié)介紹了SQL語句處理的基本過程,主要包括:
      · 查詢語句處理
      · DML語句處理(insert, update, delete)
      · DDL 語句處理(create .. , drop .. , alter .. , )
      · 事務(wù)控制(commit, rollback)

      SQL 語句的執(zhí)行過程(SQL Statement Execution)

       圖3-1 概要的列出了處理和運(yùn)行一個sql語句的需要各個重要階段。在某些情況下,Oracle運(yùn)行sql的過程可能與下面列出的各個階段的順序有所不同。如DEFINE階段可能在FETCH階段之前,這主要依賴你如何書寫代碼。

      對許多oracle的工具來說,其中某些階段會自動執(zhí)行。絕大多數(shù)用戶不需要關(guān)心各個階段的細(xì)節(jié)問題,然而,知道執(zhí)行的各個階段還是有必要的,這會幫助你寫出更高效的SQL語句來,而且還可以讓你猜測出性能差的SQL語句主要是由于哪一個階段造成的,然后我們針對這個具體的階段,找出解決的辦法。

      圖 3-1 SQL語句處理的各個階段

      DML語句的處理

      本節(jié)給出一個例子來說明在DML語句處理的各個階段到底發(fā)生了什么事情。假設(shè)你使用Pro*C程序來為指定部門的所有職員增加工資。程序已經(jīng)連到正確的用戶,你可以在你的程序中嵌入如下的SQL語句:
    EXEC SQL UPDATE employees
    SET salary = 1.10 * salary WHERE department_id = :var_department_id; var_department_id是程序變量,里面包含部門號,我們要修改該部門的職員的工資。當(dāng)這個SQL語句執(zhí)行時,使用該變量的值。

      每種類型的語句都需要如下階段:
      · 第1步: Create a Cursor 創(chuàng)建游標(biāo)
      · 第2步: Parse the Statement 分析語句
      · 第5步: Bind Any Variables 綁定變量
      · 第7步: Run the Statement 運(yùn)行語句
      · 第9步: Close the Cursor 關(guān)閉游標(biāo)

      如果使用了并行功能,還會包含下面這個階段:
      · 第6步: Parallelize the Statement 并行執(zhí)行語句

      如果是查詢語句,則需要以下幾個額外的步驟,如圖 3所示:
      · 第3步: Describe Results of a Query 描述查詢的結(jié)果集
      · 第4步: Define Output of a Query 定義查詢的輸出數(shù)據(jù)
      · 第8步: Fetch Rows of a Query 取查詢出來的行

      下面具體說一下每一步中都發(fā)生了什么事情:.

      第1步: 創(chuàng)建游標(biāo)(Create a Cursor)


    由程序接口調(diào)用創(chuàng)建一個游標(biāo)(cursor)。任何SQL語句都會創(chuàng)建它,特別在運(yùn)行DML語句時,都是自動創(chuàng)建游標(biāo)的,不需要開發(fā)人員干預(yù)。多數(shù)應(yīng)用中,游標(biāo)的創(chuàng)建是自動的。然而,在預(yù)編譯程序(pro*c)中游標(biāo)的創(chuàng)建,可能是隱含的,也可能顯式的創(chuàng)建。在存儲過程中也是這樣的。

      第2步:分析語句(Parse the Statement)

      在語法分析期間,SQL語句從用戶進(jìn)程傳送到Oracle,SQL語句經(jīng)語法分析后,SQL語句本身與分析的信息都被裝入到共享SQL區(qū)。在該階段中,可以解決許多類型的錯誤。

      語法分析分別執(zhí)行下列操作:
    l 翻譯SQL語句,驗(yàn)證它是合法的語句,即書寫正確
    l 實(shí)現(xiàn)數(shù)據(jù)字典的查找,以驗(yàn)證是否符合表和列的定義
    l 在所要求的對象上獲取語法分析鎖,使得在語句的語法分析過程中不改變這些對象的定義
    l 驗(yàn)證為存取所涉及的模式對象所需的權(quán)限是否滿足
    l 決定此語句最佳的執(zhí)行計劃
    l 將它裝入共享SQL區(qū)
    l 對分布的語句來說,把語句的全部或部分路由到包含所涉及數(shù)據(jù)的遠(yuǎn)程節(jié)點(diǎn)

      以上任何一步出現(xiàn)錯誤,都將導(dǎo)致語句報錯,中止執(zhí)行。

      只有在共享池中不存在等價SQL語句的情況下,才對SQL語句作語法分析。在這種情況下,數(shù)據(jù)庫內(nèi)核重新為該語句分配新的共享SQL區(qū),并對語句進(jìn)行語法分析。進(jìn)行語法分析需要耗費(fèi)較多的資源,所以要盡量避免進(jìn)行語法分析,這是優(yōu)化的技巧之一。

      語法分析階段包含了不管此語句將執(zhí)行多少次,而只需分析一次的處理要求。Oracle只對每個SQL語句翻譯一次,在以后再次執(zhí)行該語句時,只要該語句還在共享SQL區(qū)中,就可以避免對該語句重新進(jìn)行語法分析,也就是此時可以直接使用其對應(yīng)的執(zhí)行計劃對數(shù)據(jù)進(jìn)行存取。這主要是通過綁定變量(bind variable)實(shí)現(xiàn)的,也就是我們常說的共享SQL,后面會給出共享SQL的概念。

      雖然語法分析驗(yàn)證了SQL語句的正確性,但語法分析只能識別在SQL語句執(zhí)行之前所能發(fā)現(xiàn)的錯誤(如書寫錯誤、權(quán)限不足等)。因此,有些錯誤通過語法分析是抓不到的。例如,在數(shù)據(jù)轉(zhuǎn)換中的錯誤或在數(shù)據(jù)中的錯(如企圖在主鍵中插入重復(fù)的值)以及死鎖等均是只有在語句執(zhí)行階段期間才能遇到和報告的錯誤或情況。

      查詢語句的處理

      查詢與其它類型的SQL語句不同,因?yàn)樵诔晒?zhí)行后作為結(jié)果將返回數(shù)據(jù)。其它語句只是簡單地返回成功或失敗,而查詢則能返回一行或許多行數(shù)據(jù)。查詢的結(jié)果均采用表格形式,結(jié)果行被一次一行或者批量地被檢索出來。從這里我們可以得知批量的fetch數(shù)據(jù)可以降低網(wǎng)絡(luò)開銷,所以批量的fetch也是優(yōu)化的技巧之一。

    有些問題只與查詢處理相關(guān),查詢不僅僅指SELECT語句,同樣也包括在其它SQL語句中的隱含查詢。例如,下面的每個語句都需要把查詢作為它執(zhí)行的一部分:
    INSERT INTO table SELECT...
    UPDATE table SET x = y WHERE...
    DELETE FROM table WHERE...
    CREATE table AS SELECT...

      具體來說,查詢
    · 要求讀一致性
    · 可能使用回滾段作中間處理
    · 可能要求SQL語句處理描述、定義和取數(shù)據(jù)階段

      第3步: 描述查詢結(jié)果(Describe Results of a Query)

      描述階段只有在查詢結(jié)果的各個列是未知時才需要;例如,當(dāng)查詢由用戶交互地輸入需要輸出的列名。在這種情況要用描述階段來決定查詢結(jié)果的特征(數(shù)據(jù)類型,長度和名字)。

      第4步: 定義查詢的輸出數(shù)據(jù)(Define Output of a Query)

      在查詢的定義階段,你指定與查詢出的列值對應(yīng)的接收變量的位置、大小和數(shù)據(jù)類型,這樣我們通過接收變量就可以得到查詢結(jié)果。如果必要的話,Oracle會自動實(shí)現(xiàn)數(shù)據(jù)類型的轉(zhuǎn)換。這是將接收變量的類型與對應(yīng)的列類型相比較決定的。

      第5步: 綁定變量(Bind Any Variables)

      此時,Oracle知道了SQL語句的意思,但仍沒有足夠的信息用于執(zhí)行該語句。Oracle 需要得到在語句中列出的所有變量的值。在該例中,Oracle需要得到對department_id列進(jìn)行限定的值。得到這個值的過程就叫綁定變量(binding variables)

      此過程稱之為將變量值捆綁進(jìn)來。程序必須指出可以找到該數(shù)值的變量名(該變量被稱為捆綁變量,變量名實(shí)質(zhì)上是一個內(nèi)存地址,相當(dāng)于指針)。應(yīng)用的最終用戶可能并沒有發(fā)覺他們正在指定捆綁變量,因?yàn)镺racle 的程序可能只是簡單地指示他們輸入新的值,其實(shí)這一切都在程序中自動做了。因?yàn)槟阒付俗兞棵谀阍俅螆?zhí)行之前無須重新捆綁變量。你可以改變綁定變量的值,而Oracle在每次執(zhí)行時,僅僅使用內(nèi)存地址來查找此值。如果Oracle 需要實(shí)現(xiàn)自動數(shù)據(jù)類型轉(zhuǎn)換的話(除非它們是隱含的或缺省的),你還必須對每個值指定數(shù)據(jù)類型和長度。關(guān)于這些信息可以參考o(jì)racle的相關(guān)文檔,如Oracle Call Interface Programmer's Guide

      第6步: 并行執(zhí)行語句(Parallelize the Statement )

      ORACLE 可以在SELECTs, INSERTs, UPDATEs, MERGEs, DELETEs語句中執(zhí)行相應(yīng)并行查詢操作,對于某些DDL操作,如創(chuàng)建索引、用子查詢創(chuàng)建表、在分區(qū)表上的操作,也可以執(zhí)行并行操作。并行化可以導(dǎo)致多個服務(wù)器進(jìn)程(oracle server processes)為同一個SQL語句工作,使該SQL語句可以快速完成,但是會耗費(fèi)更多的資源,所以除非很有必要,否則不要使用并行查詢。

      第7步: 執(zhí)行語句(Run the Statement)

      到了現(xiàn)在這個時候,Oracle擁有所有需要的信息與資源,因此可以真正運(yùn)行SQL語句了。如果該語句為SELECT查詢或INSERT語句,則不需要鎖定任何行,因?yàn)闆]有數(shù)據(jù)需要被改變。然而,如果語句為UPDATE或DELETE語句,則該語句影響的所有行都被鎖定,防止該用戶提交或回滾之前,別的用戶對這些數(shù)據(jù)進(jìn)行修改。這保證了數(shù)據(jù)的一致性。對于某些語句,你可以指定執(zhí)行的次數(shù),這稱為批處理(array processing)。指定執(zhí)行N次,則綁定變量與定義變量被定義為大小為N的數(shù)組的開始位置,這種方法可以減少網(wǎng)絡(luò)開銷,也是優(yōu)化的技巧之一。

      第8步: 取出查詢的行(Fetch Rows of a Query)

      在fetch階段,行數(shù)據(jù)被取出來,每個后續(xù)的存取操作檢索結(jié)果集中的下一行數(shù)據(jù),直到最后一行被取出來。上面提到過,批量的fetch是優(yōu)化的技巧之一。

      第9步: 關(guān)閉游標(biāo)(Close the Cursor)

      SQL語句處理的最后一個階段就是關(guān)閉游標(biāo)

      DDL語句的處理(DDL Statement Processing)

      DDL語句的執(zhí)行不同與DML語句和查詢語句的執(zhí)行,這是因?yàn)镈DL語句執(zhí)行成功后需要對數(shù)據(jù)字典數(shù)據(jù)進(jìn)行修改。對于DDL語句,語句的分析階段實(shí)際上包括分析、查找數(shù)據(jù)字典信息和執(zhí)行。事務(wù)管理語句、會話管理語句、系統(tǒng)管理語句只有分析與執(zhí)行階段,為了重新執(zhí)行該語句,會重新分析與執(zhí)行該語句。

      事務(wù)控制(Control of Transactions)

      一般來說,只有使用ORACLE編程接口的應(yīng)用設(shè)計人員才關(guān)心操作的類型,并把相關(guān)的操作組織在一起,形成一個事務(wù)。一般來說,我門必須定義事務(wù),這樣在一個邏輯單元中的所有工作可以同時被提交或回滾,保證了數(shù)據(jù)的一致性。一個事務(wù)應(yīng)該由邏輯單元中的所有必須部分組成,不應(yīng)該多一個,也不應(yīng)該少一個。
      · 在事務(wù)開始和結(jié)束的這段時間內(nèi),所有被引用表中的數(shù)據(jù)都應(yīng)該在一致的狀態(tài)(或可以被回溯到一致的狀態(tài))
      · 事務(wù)應(yīng)該只包含可以對數(shù)據(jù)進(jìn)行一致更改(one consistent change to the data)的SQL語句

      例如,在兩個帳號之間的轉(zhuǎn)帳(這是一個事務(wù)或邏輯工作單元),應(yīng)該包含從一個帳號中借錢(由一個SQL完成),然后將借的錢存入另一個帳號(由另一個SQL完成)。這2個操作作為一個邏輯單元,應(yīng)該同時成功或同時失敗。其它不相關(guān)的操作,如向一個帳戶中存錢,不應(yīng)該包含在這個轉(zhuǎn)帳事務(wù)中。

      在設(shè)計應(yīng)用時,除了需要決定哪種類型的操作組成一個事務(wù)外,還需要決定使用BEGIN_DISCRETE_TRANSACTIO存儲過程是否對提高小的、非分布式的事務(wù)的性能有作用。



    [源自]http://blog.chinaunix.net/u2/61723/showart_482625.html

    posted on 2008-05-17 16:56 lqx 閱讀(612) 評論(0)  編輯  收藏 所屬分類: database

    主站蜘蛛池模板: 99免费观看视频| 国产精品免费看香蕉| 亚洲一区二区三区四区视频 | 久久久久久国产精品免费无码| 亚洲欧洲日本精品| 国产精品免费_区二区三区观看 | 亚洲人成伊人成综合网久久| 亚洲成人动漫在线观看| 女人18毛片水真多免费播放| 亚洲欧洲国产综合| 波多野结衣免费视频观看| 花蝴蝶免费视频在线观看高清版| 亚洲av产在线精品亚洲第一站| 国产亚洲大尺度无码无码专线| 91精品免费在线观看| 国产免费内射又粗又爽密桃视频 | 亚洲精品无码成人| 日本免费无遮挡吸乳视频电影| 久久九九免费高清视频| 中文字幕乱码亚洲精品一区| 亚洲永久无码3D动漫一区| 好男人视频社区精品免费| 最近国语视频在线观看免费播放 | 亚洲av无码国产精品色午夜字幕| 日韩成人免费在线| 99视频有精品视频免费观看| 男女交性无遮挡免费视频| 亚洲一区二区三区免费观看| 亚洲Av无码精品色午夜| 免费在线观看亚洲| 成人奭片免费观看| 日韩精品免费一级视频| 一级毛片免费播放试看60分钟| 亚洲AV日韩综合一区尤物| 水蜜桃亚洲一二三四在线| 亚洲精品线路一在线观看| 84pao国产成视频免费播放| 三级片免费观看久久| 亚洲精品永久在线观看| 亚洲中文久久精品无码1| 亚洲视频在线免费看|