通過分析SQL語句的執(zhí)行計(jì)劃優(yōu)化SQL_第1頁
通過分析SQL語句的執(zhí)行計(jì)劃優(yōu)化SQL_第2頁
通過分析SQL語句的執(zhí)行計(jì)劃優(yōu)化SQL_第3頁
通過分析SQL語句的執(zhí)行計(jì)劃優(yōu)化SQL_第4頁
通過分析SQL語句的執(zhí)行計(jì)劃優(yōu)化SQL_第5頁
已閱讀5頁,還剩35頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、通過分析SQL語句的執(zhí)行計(jì)劃優(yōu)化SQL(總結(jié))第1章 性能調(diào)整綜述第2章 有效的應(yīng)用設(shè)計(jì)第3章  SQL語句處理的過程第4章 ORACLE的優(yōu)化器第5章 ORACLE的執(zhí)行計(jì)劃        訪問路徑(方法) - access path        表之間的連接        如何產(chǎn)生執(zhí)行計(jì)劃        如何分析執(zhí)行計(jì)劃        如何干預(yù)執(zhí)行計(jì)劃 - - 使用hin

2、ts提示        具體案例分析第6章 其它注意事項(xiàng)附錄第1章 性能調(diào)整綜述        Oracle數(shù)據(jù)庫是高度可調(diào)的數(shù)據(jù)庫產(chǎn)品。本章描述調(diào)整的過程和那些人員應(yīng)與Oracle服務(wù)器的調(diào)整有關(guān),以及與調(diào)整相關(guān)聯(lián)的操作系統(tǒng)硬件和軟件。本章包括以下方面:l        誰來調(diào)整系統(tǒng)?l        什么時(shí)候調(diào)整?l        建立有效調(diào)整的目標(biāo)l    &#

3、160;   在設(shè)計(jì)和開發(fā)時(shí)的調(diào)整l        調(diào)整產(chǎn)品系統(tǒng)l        監(jiān)控產(chǎn)品系統(tǒng)誰來調(diào)整系統(tǒng):  為了有效地調(diào)整系統(tǒng),若干類人員必須交換信息并牽涉到系統(tǒng)調(diào)整中,例如:l        應(yīng)用設(shè)計(jì)人員必須傳達(dá)應(yīng)用系統(tǒng)的設(shè)計(jì),使得每個(gè)人都清楚應(yīng)用中的數(shù)據(jù)流動(dòng).l        應(yīng)用開發(fā)人員必須傳達(dá)他們選擇的實(shí)現(xiàn)策略,使得語句調(diào)整的過程中能快速、容易地識(shí)別有問題的應(yīng)用模塊和可疑的SQL語句.l

4、0;       數(shù)據(jù)庫管理人員必須仔細(xì)地監(jiān)控系統(tǒng)活動(dòng)并提供它們的資料,使得異常的系統(tǒng)性能可被快速得識(shí)別和糾正.l        硬件/軟件管理人員必須傳達(dá)系統(tǒng)的硬件、軟件配置并提供它們的資料,使得相關(guān)人員能有效地設(shè)計(jì)和管理系統(tǒng)。    簡(jiǎn)而言之,與系統(tǒng)涉及的每個(gè)人都在調(diào)整過程中起某些作用,當(dāng)上面提及的那些人員傳達(dá)了系統(tǒng)的特性并提供了它們的資料,調(diào)整就能相對(duì)的容易和更快一些。     不幸的是,事實(shí)上的結(jié)果是:數(shù)據(jù)庫管理員對(duì)調(diào)整負(fù)有全部或主要的責(zé)任。但是,數(shù)據(jù)庫管理

5、員很少有合適的系統(tǒng)方面的資料,而且,在很多情況下,數(shù)據(jù)庫管理員往往是在實(shí)施階段才介入數(shù)據(jù)庫,這就給調(diào)整工作帶來許多負(fù)面的影響,因?yàn)樵谠O(shè)計(jì)階段的缺陷是不能通過DBA的調(diào)整而得以解決,而設(shè)計(jì)階段的缺陷往往對(duì)數(shù)據(jù)庫性能造成極大的影響。      其實(shí),在真正成熟的開發(fā)環(huán)境下,開發(fā)人員作為純代碼編寫人員時(shí),對(duì)性能的影響最小,此時(shí)大部分的工作應(yīng)由應(yīng)用設(shè)計(jì)人員完成,而且數(shù)據(jù)庫管理員往往在前期的需求管理階段就介入,為設(shè)計(jì)人員提供必要的技術(shù)支持。調(diào)整并不是數(shù)據(jù)庫管理員的專利,相反大部分應(yīng)該是設(shè)計(jì)人員和開發(fā)人員的工作,這就需要設(shè)計(jì)人員和開發(fā)人員具體必要的數(shù)據(jù)庫知識(shí),這樣才

6、能組成一個(gè)高效的團(tuán)隊(duì),然而事實(shí)上往往并非如此。什么時(shí)候作調(diào)整?     多數(shù)人認(rèn)為當(dāng)用戶感覺性能差時(shí)才進(jìn)行調(diào)整,這對(duì)調(diào)整過程中使用某些最有效的調(diào)整策略來說往往是太遲了。此時(shí),如果你不愿意重新設(shè)計(jì)應(yīng)用的話,你只能通過重新分配內(nèi)存(調(diào)整SGA)和調(diào)整I/O的辦法或多或少地提高性能。Oracle提供了許多特性,這些特性只有應(yīng)用到正確地設(shè)計(jì)的系統(tǒng)中時(shí)才能夠很大地提高性能。      應(yīng)用設(shè)計(jì)人員需要在設(shè)計(jì)階段設(shè)置應(yīng)用的性能期望值。然后在設(shè)計(jì)和開發(fā)期間,應(yīng)用設(shè)計(jì)人員應(yīng)考慮哪些Oracle特性可以對(duì)系統(tǒng)有好處,并使用這些特性。

7、通過良好的系統(tǒng)設(shè)計(jì),你就可以在應(yīng)用的生命周期中消除性能調(diào)整的代價(jià)和挫折。圖1-1圖1-2說明在應(yīng)用的生命周期中調(diào)整的相對(duì)代價(jià)和收益,正如你見到的,最有效的調(diào)整時(shí)間是在設(shè)計(jì)階段。在設(shè)計(jì)期間的調(diào)整能以最低的代價(jià)給你最大的收益。圖1-1在應(yīng)用生命周期中調(diào)整的代價(jià)圖1-2  在應(yīng)用生命周期中調(diào)整的收益       當(dāng)然,即使在設(shè)計(jì)很好的系統(tǒng)中,也可能有性能降低。但這些性能降低應(yīng)該是可控的和可以預(yù)見的。調(diào)整目標(biāo)      不管你正在設(shè)計(jì)或維護(hù)系統(tǒng),你應(yīng)該建立專門的性能目標(biāo),它使你知道何時(shí)要作調(diào)整。如果你試

8、圖胡亂地改動(dòng)初始化參數(shù)或SQl 語句,你可能會(huì)浪費(fèi)調(diào)整系統(tǒng)的時(shí)間,而且無什么大的收益。調(diào)整你的系統(tǒng)的最有效方法如下:l        當(dāng)設(shè)計(jì)系統(tǒng)時(shí)考慮性能l        調(diào)整操作系統(tǒng)的硬件和軟件l        識(shí)別性能瓶頸l        確定問題的原因l        采取糾正的動(dòng)作當(dāng)你設(shè)計(jì)系統(tǒng)時(shí),制定專門的目標(biāo);例如,響應(yīng)時(shí)間小于秒。當(dāng)應(yīng)用不能滿足此目標(biāo)時(shí),識(shí)別造成變慢的瓶頸(例如,I/O

9、競(jìng)爭(zhēng)),確定原因,采取糾正動(dòng)作。在開發(fā)期間,你應(yīng)測(cè)試應(yīng)用研究,確定在采取應(yīng)用之前是否滿足設(shè)計(jì)的性能目標(biāo)。     當(dāng)你正在維護(hù)生產(chǎn)庫系統(tǒng)時(shí),有多種快速有效的方法來識(shí)別性能瓶頸。不管怎樣,調(diào)整通常是一系列開銷。一旦你已確定了瓶頸,你可能要犧牲一些其它方面的指標(biāo)來達(dá)到所要的結(jié)果。例如,如果I/O有問題,你可能需要更多內(nèi)存或磁盤。如果不可能買,你可能要限制系統(tǒng)的并發(fā)性,來獲取所需的性能。然而,如果你已經(jīng)明確地定義了性能的目標(biāo),那用什么來交換高性能的決策就變的很容易的,因?yàn)槟阋呀?jīng)確定了哪些方面是最重要的,如過我的目標(biāo)為高性能,可能犧牲一些空間資源。 

10、   隨著應(yīng)用的越來越龐大,硬件性能的提高,全面的調(diào)整應(yīng)用逐漸變成代價(jià)高昂的行為,在這樣情況下,要取得最大的投入/效率之比,較好的辦法是調(diào)整應(yīng)用的關(guān)鍵部分,使其達(dá)到比較高的性能,這樣從總體上來說,整個(gè)系統(tǒng)的性能也是比較高的。這也就是有名的20/80原則,調(diào)整應(yīng)用的20%(關(guān)鍵部分),能解決80%的問題。在設(shè)計(jì)和開發(fā)系統(tǒng)時(shí)作調(diào)整     良好設(shè)計(jì)的系統(tǒng)可以防止在應(yīng)用生命周期中產(chǎn)生性能問題。系統(tǒng)設(shè)計(jì)人員和應(yīng)用開發(fā)人員必須了解Oracle的查詢處理機(jī)制以便寫出高效的SQL語句?!暗?章 有效的應(yīng)用設(shè)計(jì)”討論了你的系統(tǒng)中各種可用的配

11、置,以及每種配置更適合哪種類型的應(yīng)用?!暗?章 優(yōu)化器”討論了Oracle的查詢優(yōu)化器,以及如何寫語句以獲取最快的結(jié)果。當(dāng)設(shè)計(jì)你的系統(tǒng)時(shí),使用下列優(yōu)化性能的準(zhǔn)則:l        消除客戶機(jī)服務(wù)器應(yīng)用中不必要的網(wǎng)絡(luò)傳輸。- 使用存儲(chǔ)過程。l        使用適合你系統(tǒng)的相應(yīng)Oracle服務(wù)器選件(例如,并行查詢或分布式數(shù)據(jù)庫)。l        除非你的應(yīng)用有特殊的需要,否則使用缺省的Oracle鎖。l        利用數(shù)據(jù)庫記住應(yīng)

12、用模塊,以便你能以每個(gè)模塊為基礎(chǔ)來追蹤性能。l        選擇你的數(shù)據(jù)塊的最佳大小。  - 原則上來說大一些的性能較好。l        分布你的數(shù)據(jù),使得一個(gè)節(jié)點(diǎn)使用的數(shù)據(jù)本地存貯在該節(jié)點(diǎn)中。調(diào)整產(chǎn)品系統(tǒng)     本節(jié)描述對(duì)應(yīng)用系統(tǒng)快速、容易地找出性能瓶頸,并決定糾正動(dòng)作的方法。這種方法依賴于對(duì)Oracle服務(wù)器體系結(jié)構(gòu)和特性的了解程度。在試圖調(diào)整你的系統(tǒng)前,你應(yīng)熟悉Oracle調(diào)整的內(nèi)容。為調(diào)整你已有的系統(tǒng),遵從下列步驟:l   

13、;     調(diào)整操作系統(tǒng)的硬件和軟件l        通過查詢V $SESSION_WAIT視圖,識(shí)別性能的瓶頸,這個(gè)動(dòng)態(tài)性能視圖列出了造成會(huì)話(session)等待的事件。l        通過分析V $SESSION_WAIT中的數(shù)據(jù),決定瓶頸的原因。l        糾正存在的問題。監(jiān)控應(yīng)用系統(tǒng)這主要是通過監(jiān)控oracle的動(dòng)態(tài)視圖來完成。各種有用的動(dòng)態(tài)視圖:如v$session_wait, v$session_event等。   

14、;                                   第2章 有效的應(yīng)用設(shè)計(jì)        我們通常將最常用的應(yīng)用分為2種類型:聯(lián)機(jī)事務(wù)處理類型(OLTP),決策支持系統(tǒng)(DSS)。聯(lián)機(jī)事務(wù)處理(OLTP)        該類型的應(yīng)用是高吞吐量,插入、更新、刪除

15、操作比較多的系統(tǒng),這些系統(tǒng)以不斷增長(zhǎng)的大容量數(shù)據(jù)為特征,它們提供給成百用戶同時(shí)存取,典型的OLTP系統(tǒng)是訂票系統(tǒng),銀行的業(yè)務(wù)系統(tǒng),訂單系統(tǒng)。OTLP的主要目標(biāo)是可用性、速度、并發(fā)性和可恢復(fù)性。        當(dāng)設(shè)計(jì)這類系統(tǒng)時(shí),必須確保大量的并發(fā)用戶不能干擾系統(tǒng)的性能。還需要避免使用過量的索引與cluster 表,因?yàn)檫@些結(jié)構(gòu)會(huì)使插入和更新操作變慢。決策支持(DSS)        該類型的應(yīng)用將大量信息進(jìn)行提取形成報(bào)告,協(xié)助決策者作出正確的判斷。典型的情況是:決策支持系統(tǒng)將OLTP應(yīng)用收集的大量數(shù)據(jù)進(jìn)行查詢。典型的

16、應(yīng)用為客戶行為分析系統(tǒng)(超市,保險(xiǎn)等)。        決策支持的關(guān)鍵目標(biāo)是速度、精確性和可用性。        該種類型的設(shè)計(jì)往往與OLTP設(shè)計(jì)的理念背道而馳,一般建議使用數(shù)據(jù)冗余、大量索引、cluster table、并行查詢等。        近年來,該類型的應(yīng)用逐漸與OLAP、數(shù)據(jù)倉庫緊密的聯(lián)系在一起,形成的一個(gè)新的應(yīng)用方向。第3章  SQL語句處理的過程           &

17、#160;  在調(diào)整之前我們需要了解一些背景知識(shí),只有知道這些背景知識(shí),我們才能更好的去調(diào)整sql語句。本節(jié)介紹了SQL語句處理的基本過程,主要包括:·        查詢語句處理 ·        DML語句處理(insert, update, delete) ·        DDL 語句處理(create . , drop . , alter . , ) ·   

18、;     事務(wù)控制(commit, rollback) SQL 語句的執(zhí)行過程(SQL Statement Execution)             圖3-1 概要的列出了處理和運(yùn)行一個(gè)sql語句的需要各個(gè)重要階段。在某些情況下,Oracle運(yùn)行sql的過程可能與下面列出的各個(gè)階段的順序有所不同。如DEFINE階段可能在FETCH階段之前,這主要依賴你如何書寫代碼。            對(duì)許多ora

19、cle的工具來說,其中某些階段會(huì)自動(dòng)執(zhí)行。絕大多數(shù)用戶不需要關(guān)心各個(gè)階段的細(xì)節(jié)問題,然而,知道執(zhí)行的各個(gè)階段還是有必要的,這會(huì)幫助你寫出更高效的SQL語句來,而且還可以讓你猜測(cè)出性能差的SQL語句主要是由于哪一個(gè)階段造成的,然后我們針對(duì)這個(gè)具體的階段,找出解決的辦法。圖 3-1  SQL語句處理的各個(gè)階段DML語句的處理      本節(jié)給出一個(gè)例子來說明在DML語句處理的各個(gè)階段到底發(fā)生了什么事情。假設(shè)你使用Pro*C程序來為指定部門的所有職員增加工資。程序已經(jīng)連到正確的用戶,你可以在你的程序中嵌入如下的SQL語句:EXEC SQL

20、UPDATE employees SET salary = 1.10 * salary             WHERE department_id = :var_department_id; var_department_id是程序變量,里面包含部門號(hào),我們要修改該部門的職員的工資。當(dāng)這個(gè)SQL語句執(zhí)行時(shí),使用該變量的值。每種類型的語句都需要如下階段:·        第1步: Create a Cursor   

21、;  創(chuàng)建游標(biāo)(語句執(zhí)行緩沖區(qū))·        第2步: Parse the Statement  分析語句·        第5步: Bind Any Variables    綁定變量·        第7步: Run the Statement    運(yùn)行語句·        第9步: Close the Cu

22、rsor     關(guān)閉游標(biāo)如果使用了并行功能,還會(huì)包含下面這個(gè)階段:·        第6步: Parallelize the Statement   并行執(zhí)行語句如果是查詢語句,則需要以下幾個(gè)額外的步驟,如圖 3所示:·        第3步: Describe Results of a Query   描述查詢的結(jié)果集·        第4步: Define Ou

23、tput of a Query      定義查詢的輸出數(shù)據(jù)·        第8步: Fetch Rows of a Query        取查詢出來的行下面具體說一下每一步中都發(fā)生了什么事情:.第1步: 創(chuàng)建游標(biāo)(Create a Cursor)        由程序接口調(diào)用創(chuàng)建一個(gè)游標(biāo)(cursor)。任何SQL語句都會(huì)創(chuàng)建它,特別在運(yùn)行DML語句時(shí),都是自動(dòng)創(chuàng)建游標(biāo)的,不需要

24、開發(fā)人員干預(yù)。多數(shù)應(yīng)用中,游標(biāo)的創(chuàng)建是自動(dòng)的。然而,在預(yù)編譯程序(pro*c)中游標(biāo)的創(chuàng)建,可能是隱含的,也可能顯式的創(chuàng)建。在存儲(chǔ)過程中也是這樣的。第2步:分析語句(Parse the Statement)       在語法分析期間,SQL語句從用戶進(jìn)程傳送到Oracle,SQL語句經(jīng)語法分析后,SQL語句本身與分析的信息都被裝入到共享SQL區(qū)。在該階段中,可以解決許多類型的錯(cuò)誤。語法分析分別執(zhí)行下列操作:l        翻譯SQL語句,驗(yàn)證它是合法的語句,即書寫正確l     

25、  實(shí)現(xiàn)數(shù)據(jù)字典的查找,以驗(yàn)證是否符合表和列的定義l        在所要求的對(duì)象上獲取語法分析鎖,使得在語句的語法分析過程中不改變這些對(duì)象的定義。(如果在分析并執(zhí)行過后,對(duì)象的定義改變了,那么該sql語句還會(huì)共享么?共享也可能沒有用處了吧?)l        驗(yàn)證為存取所涉及的模式對(duì)象所需的權(quán)限是否滿足l        決定此語句最佳的執(zhí)行計(jì)劃l        將它裝入共享SQL區(qū)l     

26、  對(duì)分布的語句來說,把語句的全部或部分路由到包含所涉及數(shù)據(jù)的遠(yuǎn)程節(jié)點(diǎn)      以上任何一步出現(xiàn)錯(cuò)誤,都將導(dǎo)致語句報(bào)錯(cuò),中止執(zhí)行。      只有在共享池中不存在等價(jià)SQL語句的情況下,才對(duì)SQL語句作語法分析(有問題吧,語法、表列定義、權(quán)限還是會(huì)先做分析的吧?)。在這種情況下,數(shù)據(jù)庫內(nèi)核重新為該語句分配新的共享SQL區(qū),并對(duì)語句進(jìn)行語法分析。進(jìn)行語法分析需要耗費(fèi)較多的資源,所以要盡量避免進(jìn)行語法分析,這是優(yōu)化的技巧之一。      語法分析階段包含了不管此語句將

27、執(zhí)行多少次,而只需分析一次的處理要求。Oracle只對(duì)每個(gè)SQL語句翻譯一次,在以后再次執(zhí)行該語句時(shí),只要該語句還在共享SQL區(qū)中,就可以避免對(duì)該語句重新進(jìn)行語法分析,也就是此時(shí)可以直接使用其對(duì)應(yīng)的執(zhí)行計(jì)劃(語法分析、對(duì)象確認(rèn)、權(quán)限檢查還是都會(huì)有的吧?)對(duì)數(shù)據(jù)進(jìn)行存取。這主要是通過綁定變量(bind variable)實(shí)現(xiàn)的,也就是我們常說的共享SQL,后面會(huì)給出共享SQL的概念。     雖然語法分析驗(yàn)證了SQL語句的正確性,但語法分析只能識(shí)別在SQL語句執(zhí)行之前所能發(fā)現(xiàn)的錯(cuò)誤(如書寫錯(cuò)誤、權(quán)限不足等)。因此,有些錯(cuò)誤通過語法分析是抓不到的。例如,在數(shù)

28、據(jù)轉(zhuǎn)換中的錯(cuò)誤或在數(shù)據(jù)中的錯(cuò)(如企圖在主鍵中插入重復(fù)的值)以及死鎖等均是只有在語句執(zhí)行階段期間才能遇到和報(bào)告的錯(cuò)誤或情況。查詢語句的處理      查詢與其它類型的SQL語句不同,因?yàn)樵诔晒?zhí)行后作為結(jié)果將返回?cái)?shù)據(jù)。其它語句只是簡(jiǎn)單地返回成功或失敗,而查詢則能返回一行或許多行數(shù)據(jù)。查詢的結(jié)果均采用表格形式,結(jié)果行被一次一行或者批量地被檢索出來。從這里我們可以得知批量的fetch數(shù)據(jù)可以降低網(wǎng)絡(luò)開銷,所以批量的fetch也是優(yōu)化的技巧之一。       有些問題只與查詢處理相關(guān),查詢不僅僅指SELECT語句,同樣也包

29、括在其它SQL語句中的隱含查詢。例如,下面的每個(gè)語句都需要把查詢作為它執(zhí)行的一部分:INSERT INTO table SELECT. UPDATE table SET x = y WHERE. DELETE FROM table WHERE. CREATE table AS SELECT. 具體來說,查詢·        要求讀一致性·        可能使用回滾段作中間處理·        可能要求SQ

30、L語句處理描述、定義和取數(shù)據(jù)階段第3步: 描述查詢結(jié)果(Describe Results of a Query)      描述階段只有在查詢結(jié)果的各個(gè)列是未知時(shí)才需要;例如,當(dāng)查詢由用戶交互地輸入需要輸出的列名。在這種情況要用描述階段來決定查詢結(jié)果的特征(數(shù)據(jù)類型,長(zhǎng)度和名字)。第4步: 定義查詢的輸出數(shù)據(jù)(Define Output of a Query)         在查詢的定義階段,你指定與查詢出的列值對(duì)應(yīng)的接收變量的位置、大小和數(shù)據(jù)類型,這樣我們通過接收變量就可以得到查詢結(jié)果。如果

31、必要的話,Oracle會(huì)自動(dòng)實(shí)現(xiàn)數(shù)據(jù)類型的轉(zhuǎn)換。這是將接收變量的類型與對(duì)應(yīng)的列類型相比較決定的。第5步: 綁定變量(Bind Any Variables)(綁定變量是在語句解析過程中做的,而以后執(zhí)行語句只是尋找變量值,是這個(gè)意思么?)      此時(shí),Oracle知道了SQL語句的意思,但仍沒有足夠的信息用于執(zhí)行該語句。Oracle 需要得到在語句中列出的所有變量的值(得到變量的值)。在該例中,Oracle需要得到對(duì)department_id列進(jìn)行限定的值。得到這個(gè)值的過程就叫綁定變量(binding variables)   

32、60;  此過程稱之為將變量值捆綁進(jìn)來。程序(是指sql語句吧?)必須指出可以找到該數(shù)值的變量名(該變量被稱為捆綁變量(為甚么叫捆綁變量,是因?yàn)槠渖辖壎ǖ挠兄得??),變量名?shí)質(zhì)上是一個(gè)內(nèi)存地址,相當(dāng)于指針)。應(yīng)用的最終用戶可能并沒有發(fā)覺他們正在指定捆綁變量,因?yàn)镺racle 的程序可能只是簡(jiǎn)單地指示他們輸入新的值,其實(shí)這一切都在程序中自動(dòng)做了。      因?yàn)槟阒付俗兞棵谀阍俅螆?zhí)行之前無須重新捆綁變量。你可以改變綁定變量的值,而Oracle在每次執(zhí)行時(shí),僅僅使用內(nèi)存地址來查找此值。       如果

33、Oracle 需要實(shí)現(xiàn)自動(dòng)數(shù)據(jù)類型轉(zhuǎn)換的話(除非它們是隱含的或缺省的),你還必須對(duì)每個(gè)值指定數(shù)據(jù)類型和長(zhǎng)度。關(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)并行查詢操作,對(duì)于某些DDL操作,如創(chuàng)建索引、用子查詢創(chuàng)建表、在分區(qū)表上的操作,也可以執(zhí)行并行操作。并行化可以導(dǎo)

34、致多個(gè)服務(wù)器進(jìn)程(oracle server processes)為同一個(gè)SQL語句工作,使該SQL語句可以快速完成,但是會(huì)耗費(fèi)更多的資源,所以除非很有必要,否則不要使用并行查詢。第7步: 執(zhí)行語句(Run the Statement)      到了現(xiàn)在這個(gè)時(shí)候,Oracle擁有所有需要的信息與資源,因此可以真正運(yùn)行SQL語句了。如果該語句為SELECT查詢或INSERT語句,則不需要鎖定任何行,因?yàn)闆]有數(shù)據(jù)需要被改變。然而,如果語句為UPDATE或DELETE語句,則該語句影響的所有行都被鎖定,防止該用戶提交或回滾之前,別的用戶對(duì)這些數(shù)據(jù)進(jìn)行修改。這

35、保證了數(shù)據(jù)的一致性。     對(duì)于某些語句,你可以指定執(zhí)行的次數(shù),這稱為批處理(array processing)。指定執(zhí)行N次,則綁定變量與定義變量被定義為大小為N的數(shù)組的開始位置,這種方法可以減少網(wǎng)絡(luò)開銷,也是優(yōu)化的技巧之一。第8步: 取出查詢的行(Fetch Rows of a Query)      在fetch階段,行數(shù)據(jù)被取出來,每個(gè)后續(xù)的存取操作檢索結(jié)果集中的下一行數(shù)據(jù),直到最后一行被取出來。上面提到過,批量的fetch是優(yōu)化的技巧之一。第9步: 關(guān)閉游標(biāo)(Close the Cursor) 

36、;     SQL語句處理的最后一個(gè)階段就是關(guān)閉游標(biāo)DDL語句的處理(DDL Statement Processing)     DDL語句的執(zhí)行不同與DML語句和查詢語句的執(zhí)行,這是因?yàn)镈DL語句執(zhí)行成功后需要對(duì)數(shù)據(jù)字典數(shù)據(jù)進(jìn)行修改。對(duì)于DDL語句,語句的分析階段實(shí)際上包括分析、查找數(shù)據(jù)字典信息和執(zhí)行。     事務(wù)管理語句、會(huì)話管理語句、系統(tǒng)管理語句只有分析與執(zhí)行階段,為了重新執(zhí)行該語句,會(huì)重新分析與執(zhí)行該語句。事務(wù)控制(Control of Transactions) 

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

38、 consistent change to the data)的SQL語句      例如,在兩個(gè)帳號(hào)之間的轉(zhuǎn)帳(這是一個(gè)事務(wù)或邏輯工作單元),應(yīng)該包含從一個(gè)帳號(hào)中借錢(由一個(gè)SQL完成),然后將借的錢存入另一個(gè)帳號(hào)(由另一個(gè)SQL完成)。這2個(gè)操作作為一個(gè)邏輯單元,應(yīng)該同時(shí)成功或同時(shí)失敗。其它不相關(guān)的操作,如向一個(gè)帳戶中存錢,不應(yīng)該包含在這個(gè)轉(zhuǎn)帳事務(wù)中。      在設(shè)計(jì)應(yīng)用時(shí),除了需要決定哪種類型的操作組成一個(gè)事務(wù)外,還需要決定使用BEGIN_DISCRETE_TRANSACTIO存儲(chǔ)過程是否對(duì)提高小的、非分布

39、式的事務(wù)的性能有作用。第4章 ORACLE的優(yōu)化器        優(yōu)化器有時(shí)也被稱為查詢優(yōu)化器,這是因?yàn)椴樵兪怯绊憯?shù)據(jù)庫性能最主要的部分,不要以為只有SELECT語句是查詢。實(shí)際上,帶有任何WHERE條件的DML(INSERT、UPDATE、DELETE)語句中都包含查詢要求,在后面的文章中,當(dāng)說到查詢時(shí),不一定只是指SELECT語句,也有可能指DML語句中的查詢部分。優(yōu)化器是所有關(guān)系數(shù)據(jù)庫引擎中的最神秘、最富挑戰(zhàn)性的部件之一,從性能的角度看也是最重要的部分,它性能的高低直接關(guān)系到數(shù)據(jù)庫性能的好壞。       

40、我們知道,SQL語句同其它語言(如C語言)的語句不一樣,它是非過程化(non-procedural)的語句,即當(dāng)你要取數(shù)據(jù)時(shí),不需要告訴數(shù)據(jù)庫通過何種途徑去取數(shù)據(jù),如到底是通過索引取數(shù)據(jù),還是應(yīng)該將表中的每行數(shù)據(jù)都取出來,然后再通過一一比較的方式取數(shù)據(jù)(即全表掃描),這是由數(shù)據(jù)庫的優(yōu)化器決定的,這就是非過程化的含義,也就是說,如何取數(shù)據(jù)是由優(yōu)化器決定,而不是應(yīng)用開發(fā)者通過編程決定。在處理SQL的SELECT、UPDATE、INSERT或DELETE語句時(shí),Oracle 必須訪問語句所涉及的數(shù)據(jù),Oracle的優(yōu)化器部分用來決定訪問數(shù)據(jù)的有效路徑,使得語句執(zhí)行所需的I/O和處理時(shí)間最小。

41、0;       為了實(shí)現(xiàn)一個(gè)查詢,內(nèi)核必須為每個(gè)查詢定制一個(gè)查詢策略,或?yàn)槿〕龇蠗l件的數(shù)據(jù)生成一個(gè)執(zhí)行計(jì)劃(execution plan)。典型的,對(duì)于同一個(gè)查詢,可能有幾個(gè)執(zhí)行計(jì)劃都符合要求,都能得到符合條件的數(shù)據(jù)。例如,參與連接的表可以有多種不同的連接方法,這取決于連接條件和優(yōu)化器采用的連接方法。為了在多個(gè)執(zhí)行計(jì)劃中選擇最優(yōu)的執(zhí)行計(jì)劃,優(yōu)化器必須使用一些實(shí)際的指標(biāo)來衡量每個(gè)執(zhí)行計(jì)劃使用的資源(I/0次數(shù)、CPU等),這些資源也就是我們所說的代價(jià)(cost)。如果一個(gè)執(zhí)行計(jì)劃使用的資源多,我們就說使用執(zhí)行計(jì)劃的代價(jià)大。以執(zhí)行計(jì)劃的代價(jià)大小作為衡量標(biāo)準(zhǔn),優(yōu)化器

42、選擇代價(jià)最小的執(zhí)行計(jì)劃作為真正執(zhí)行該查詢的執(zhí)行計(jì)劃,并拋棄其它的執(zhí)行計(jì)劃。        在ORACLE的發(fā)展過程中,一共開發(fā)過2種類型的優(yōu)化器:基于規(guī)則的優(yōu)化器和基于代價(jià)的優(yōu)化器。這2種優(yōu)化器的不同之處關(guān)鍵在于:取得代價(jià)的方法與衡量代價(jià)的大小的方法不同?,F(xiàn)對(duì)每種優(yōu)化器做一下簡(jiǎn)單的介紹:基于規(guī)則的優(yōu)化器 - Rule Based (Heuristic) Optimization(簡(jiǎn)稱RBO):        在ORACLE7之前,主要是使用基于規(guī)則的優(yōu)化器。ORACLE在基于規(guī)則的優(yōu)化器中采用啟發(fā)式的方法(Heur

43、istic Approach)或規(guī)則(Rules)來生成執(zhí)行計(jì)劃。例如,如果一個(gè)查詢的where條件(where clause)包含一個(gè)謂詞(predicate,其實(shí)就是一個(gè)判斷條件,如”=”, “>”, ”<”等),而且該謂詞上引用的列上有有效索引,那么優(yōu)化器將使用索引訪問這個(gè)表,而不考慮其它因素,如表中數(shù)據(jù)的多少、表中數(shù)據(jù)的易變性、索引的可選擇性等。此時(shí)數(shù)據(jù)庫中沒有關(guān)于表與索引數(shù)據(jù)的統(tǒng)計(jì)性描述,如表中有多上行,每行的可選擇性等。優(yōu)化器也不考慮實(shí)例參數(shù),如multi block i/o、可用排序內(nèi)存的大小等,所以優(yōu)化器有時(shí)就選擇了次優(yōu)化的計(jì)劃作為真正的執(zhí)行計(jì)劃,導(dǎo)致系統(tǒng)性能不高。

44、        如,對(duì)于        select * from emp where deptno = 10;        這個(gè)查詢來說,如果是使用基于規(guī)則的優(yōu)化器,而且deptno列上有有效的索引,則會(huì)通過deptno列上的索引來訪問emp表。在絕大多數(shù)情況下,這是比較高效的,但是在一些特殊情況下,使用索引訪問也有比較低效的時(shí)候,現(xiàn)舉例說明:        1) emp表比較小,該表的數(shù)據(jù)只存放在幾個(gè)數(shù)據(jù)塊中。此時(shí)使用全表掃描比使

45、用索引訪問emp表反而要好。因?yàn)楸肀容^小,極有可能數(shù)據(jù)全在內(nèi)存中,所以此時(shí)做全表掃描是最快的。而如果使用索引掃描,需要先從索引中找到符合條件記錄的rowid,然后再一一根據(jù)這些rowid從emp中將數(shù)據(jù)取出來,在這種條件下,效率就會(huì)比全表掃描的效率要差一些。        2) emp表比較大時(shí),而且deptno = 10條件能查詢出表中大部分的數(shù)據(jù)如(50%)。如該表共有4000萬行數(shù)據(jù),共放在有500000個(gè)數(shù)據(jù)塊中,每個(gè)數(shù)據(jù)塊為8k,則該表共有約4G,則這么多的數(shù)據(jù)不可能全放在內(nèi)存中,絕大多數(shù)需要放在硬盤上。此時(shí)如果該查詢通過索引查詢,則是你夢(mèng)魘的

46、開始。db_file_multiblock_read_count參數(shù)的值200。如果采用全表掃描,則需要500000/db_file_multiblock_read_count=500000/200=2500次I/O。但是如果采用索引掃描,假設(shè)deptno列上的索引都已經(jīng)cache到內(nèi)存中,所以可以將訪問索引的開銷忽略不計(jì)。因?yàn)橐x出4000萬x 50% = 2000萬數(shù)據(jù),假設(shè)在讀這2000萬數(shù)據(jù)時(shí),有99.9%的命中率,則還是需要20000次I/O,比上面的全表掃描需要的2500次多多了,所以在這種情況下,用索引掃描反而性能會(huì)差很多。在這樣的情況下,用全表掃描的時(shí)間是固定的,但是用索引掃描

47、的時(shí)間會(huì)隨著選出數(shù)據(jù)的增多使查詢時(shí)間相應(yīng)的延長(zhǎng)。        上面是枯燥的假設(shè)數(shù)據(jù),現(xiàn)在以具體的實(shí)例給予驗(yàn)證:        環(huán)境: oracle 817 + linux + 陣列柜,表SWD_BILLDETAIL有3200多萬數(shù)據(jù);                表的id列、cn列上都有索引        經(jīng)查看執(zhí)行計(jì)劃,發(fā)現(xiàn)執(zhí)行select count(id) from SWD_BILLDE

48、TAIL;使用全表掃描,執(zhí)行完用了大約1.50分鐘(4次執(zhí)行取平均,每次分別為1.45 1.51 2.00 1.46)(這個(gè)應(yīng)該是有問題的,如果在id列上有索引,這個(gè)查詢語句只需掃描索引就可以得到結(jié)果了,而非使用全表掃描,如果是要使用全表掃描則應(yīng)該count()表中沒有索引的列)。而執(zhí)行select count(id) from SWD_BILLDETAIL where cn <'6'卻用了2個(gè)小時(shí)還沒有執(zhí)行完,經(jīng)分析該語句使用了cn列上的索引,然后利用查詢出的rowid再?gòu)谋碇胁樵償?shù)據(jù)。我為什么不使用select count(cn) from SWD_BILLDETAI

49、L where cn <'6'呢?后面在分析執(zhí)行路徑的索引掃描時(shí)時(shí)會(huì)給出說明。        下面就是基于規(guī)則的優(yōu)化器使用的執(zhí)行路徑與各個(gè)路徑對(duì)應(yīng)的等級(jí):        RBO Path 1: Single Row by Rowid(等級(jí)最高)        RBO Path 2: Single Row by Cluster Join        RBO Path 3: Single Row by Hash Cl

50、uster Key with Unique or Primary Key        RBO Path 4: Single Row by Unique or Primary Key        RBO Path 5: Clustered Join        RBO Path 6: Hash Cluster Key        RBO Path 7: Indexed Cluster Key     

51、   RBO Path 8: Composite Index        RBO Path 9: Single-Column Indexes        RBO Path 10: Bounded Range Search on Indexed Columns        RBO Path 11: Unbounded Range Search on Indexed Columns        RBO Path 12: S

52、ort Merge Join        RBO Path 13: MAX or MIN of Indexed Column        RBO Path 14: ORDER BY on Indexed Column        RBO Path 15: Full Table Scan(等級(jí)最低)        上面的執(zhí)行路徑中,RBO認(rèn)為越往下執(zhí)行的代價(jià)越大,即等級(jí)越低。在RBO生成執(zhí)行計(jì)劃時(shí),如果它發(fā)現(xiàn)有等級(jí)高的執(zhí)行路徑可用,

53、則肯定會(huì)使用等級(jí)高的路徑,而不管任何其它影響性能的元素,即RBO通過上面的路徑的等級(jí)決定執(zhí)行路徑的代價(jià),執(zhí)行路徑的等級(jí)越高,則使用該執(zhí)行路徑的代價(jià)越小。如上面2個(gè)例子所述,如果使用RBO,則肯定使用索引訪問表,也就是選擇了比較差的執(zhí)行計(jì)劃,這樣會(huì)給數(shù)據(jù)庫性能帶來很大的負(fù)面影響。為了解決這個(gè)問題,從ORACLE 7開始o(jì)racle引入了基于代價(jià)的優(yōu)化器,下面給出了介紹?;诖鷥r(jià)的優(yōu)化器 - Cost Based Optimization(簡(jiǎn)稱CBO)        Oracle把一個(gè)代價(jià)引擎(Cost Engine)集成到數(shù)據(jù)庫內(nèi)核中,用來估計(jì)每個(gè)執(zhí)行計(jì)劃

54、需要的代價(jià),該代價(jià)將每個(gè)執(zhí)行計(jì)劃所耗費(fèi)的資源進(jìn)行量化,從而CBO可以根據(jù)這個(gè)代價(jià)選擇出最優(yōu)的執(zhí)行計(jì)劃。一個(gè)查詢耗費(fèi)的資源可以被分成3個(gè)基本組成部分:I/O代價(jià)、CPU代價(jià)、network代價(jià)。I/O代價(jià)是將數(shù)據(jù)從磁盤讀入內(nèi)存所需的代價(jià)。訪問數(shù)據(jù)包括將數(shù)據(jù)文件中數(shù)據(jù)塊的內(nèi)容讀入到SGA的數(shù)據(jù)高速緩存中,在一般情況下,該代價(jià)是處理一個(gè)查詢所需要的最主要代價(jià),所以我們?cè)趦?yōu)化時(shí),一個(gè)基本原則就是降低查詢所產(chǎn)生的I/O總次數(shù)(注意這里說的是次數(shù))。CPU代價(jià)是處理在內(nèi)存中數(shù)據(jù)所需要的代價(jià),如一旦數(shù)據(jù)被讀入內(nèi)存,則我們?cè)谧R(shí)別出我們需要的數(shù)據(jù)后,在這些數(shù)據(jù)上執(zhí)行排序(sort)或連接(join)操作,這需要

55、耗費(fèi)CPU資源。        對(duì)于需要訪問跨節(jié)點(diǎn)(即通常說的服務(wù)器)數(shù)據(jù)庫上數(shù)據(jù)的查詢來說,存在network代價(jià),用來量化傳輸操作耗費(fèi)的資源。查詢遠(yuǎn)程表的查詢或執(zhí)行分布式連接的查詢會(huì)在network代價(jià)方面花費(fèi)比較大。        在使用CBO時(shí),需要有表和索引的統(tǒng)計(jì)數(shù)據(jù)(分析數(shù)據(jù))作為基礎(chǔ)數(shù)據(jù),有了這些數(shù)據(jù)做依據(jù),CBO才能為各個(gè)執(zhí)行計(jì)劃計(jì)算出相對(duì)準(zhǔn)確的代價(jià),從而使CBO選擇最佳的執(zhí)行計(jì)劃。所以定期的對(duì)表、索引進(jìn)行分析是絕對(duì)必要的,這樣才能使統(tǒng)計(jì)數(shù)據(jù)反映數(shù)據(jù)庫中的真實(shí)情況。否則就會(huì)使CBO選擇較差的執(zhí)行計(jì)劃

56、,影響數(shù)據(jù)庫的性能。分析操作不必做的太頻繁,一般來說,每星期一次就足夠了。切記如果想使用CBO,則必須定期對(duì)表和索引進(jìn)行分析。        對(duì)于分析用的命令,隨著數(shù)據(jù)庫版本的升級(jí),用的命令也發(fā)生了變換,在oracle 8i以前,主要是用ANALYZE命令。在ORACLE 8I以后,又引入了DBMS_STATS存儲(chǔ)包來進(jìn)行分析。幸運(yùn)的是從ORACLE 10G以后,分析工作變成自動(dòng)的了,這減輕的DBA的負(fù)擔(dān),不過在一些特殊情況下,還需要一些手工分析。        如果采用了CBO優(yōu)化器,而沒有對(duì)表和索引進(jìn)行分析,沒

57、有統(tǒng)計(jì)數(shù)據(jù),則ORACLE使用缺省的統(tǒng)計(jì)數(shù)據(jù)(至少在ORACLE 9I中是這樣),這可以從oracle的文檔上找到。使用的缺省值肯定與系統(tǒng)的實(shí)際統(tǒng)計(jì)值不一致,這可能會(huì)導(dǎo)致優(yōu)化器選擇錯(cuò)誤的執(zhí)行計(jì)劃,影響數(shù)據(jù)庫的性能。        要注意的是:雖然CBO的功能隨著ORACLE新版本的推出,功能越來越強(qiáng),但它不是能包治百病的神藥,否則就不再需要DBA了,那我就慘了!實(shí)際上任何一個(gè)語句,隨著硬件環(huán)境與應(yīng)用數(shù)據(jù)的不同,該語句的執(zhí)行計(jì)劃可能需要隨之發(fā)生變化,這樣才能取得最好的性能。所以有時(shí)候不在具體的環(huán)境下而進(jìn)行SQL性能調(diào)整是徒勞的。   

58、    在ORACLE8I推出的時(shí)候,ORACLE極力建議大家使用CBO,說CBO有種種好處,但是在那是ORACLE開發(fā)的應(yīng)用系統(tǒng)還是使用基于規(guī)則的優(yōu)化器,從這件事上我們可以得出這樣的結(jié)論:1) 如果團(tuán)隊(duì)的數(shù)據(jù)庫水平很高而且都熟悉應(yīng)用數(shù)據(jù)的特點(diǎn),RBO也可以取得很好的性能。2)CBO不是很穩(wěn)定,但是一個(gè)比較有前途的優(yōu)化器,Oracle極力建議大家用是為了讓大家盡快發(fā)現(xiàn)它的BUG,以便進(jìn)一步改善,但是ORACLE為了對(duì)自己開發(fā)的應(yīng)用系統(tǒng)負(fù)責(zé),他們還是使用了比較熟悉而且成熟的RBO。從這個(gè)事情上給我們的啟發(fā)就是:我們?cè)谝院蟮拈_發(fā)中,應(yīng)該盡量采用我們熟悉并且成熟的技術(shù),而不要一味

59、的采用新技術(shù),一味采用新技術(shù)并不一定能開發(fā)出好的產(chǎn)品。幸運(yùn)的是從ORACLE 10G后,CBO已經(jīng)足夠的強(qiáng)大與智能,大家可以放心的使用該技術(shù),因?yàn)镺RACLE 10G后,Oracle自己開發(fā)的應(yīng)用系統(tǒng)也使用CBO優(yōu)化器了。而且ORACLE規(guī)定,從ORACLE 10G開始,開始廢棄RBO優(yōu)化器。這句話并不是指在ORACLE 10G中不能使用RBO,而是從ORACLE 10G開始開始,不再為RBO的BUG提供修補(bǔ)服務(wù)。        在上面的第2個(gè)例子中,如果采用CBO優(yōu)化器,它就會(huì)考慮emp表的行數(shù),deptno列的統(tǒng)計(jì)數(shù)據(jù),發(fā)現(xiàn)對(duì)該列做查詢會(huì)查詢出過多的

60、數(shù)據(jù),并且考慮db_file_multiblock_read_count參數(shù)的設(shè)置,發(fā)現(xiàn)用全表掃描的代價(jià)比用索引掃描的代價(jià)要小,從而使用全表掃描從而取得良好的執(zhí)行性能。        判斷當(dāng)前數(shù)據(jù)庫使用何種優(yōu)化器:        主要是由optimizer_mode初始化參數(shù)決定的。該參數(shù)可能的取值為:first_rows_1 | 10 | 100 | 1000 | first_rows | all_rows | (前面這些個(gè)都是cbo中一種特例,隸屬于cbo,它們會(huì)影響到oracle到底采用哪種連接方式

61、)choose | rule。具體解釋如下:        RULE為使用RBO優(yōu)化器。        CHOOSE則是根據(jù)實(shí)際情況,如果數(shù)據(jù)字典中包含被引用的表的統(tǒng)計(jì)數(shù)據(jù),即引用的對(duì)象已經(jīng)被分析,則就使用CBO優(yōu)化器,否則為RBO優(yōu)化器。        ALL_ROWS為CBO優(yōu)化器使用的第一種具體的優(yōu)化方法,是以數(shù)據(jù)的吞吐量為主要目標(biāo),以便可以使用最少的資源完成語句。        FIRST_ROWS為優(yōu)化器使用的第二種具體的優(yōu)化

62、方法,是以數(shù)據(jù)的響應(yīng)時(shí)間為主要目標(biāo),以便快速查詢出開始的幾行數(shù)據(jù)。        FIRST_ROWS_1 | 10 | 100 | 1000 為優(yōu)化器使用的第三種具體的優(yōu)化方法,讓優(yōu)化器選擇一個(gè)能夠把響應(yīng)時(shí)間減到最小的查詢執(zhí)行計(jì)劃,以迅速產(chǎn)生查詢結(jié)果的前 n 行。該參數(shù)為ORACLE 9I新引入的。        從ORACLE V7以來,optimizer_mode參數(shù)的缺省設(shè)置應(yīng)是"choose",即如果對(duì)已分析的表查詢的話選擇CBO,否則選擇RBO。在此種設(shè)置中,如果采用了CBO,則缺省

63、為CBO中的all_rows模式。        注意:即使指定數(shù)據(jù)庫使用RBO優(yōu)化器,但有時(shí)ORACLE數(shù)據(jù)庫還是會(huì)采用CBO優(yōu)化器,這并不是ORACLE的BUG,主要是由于從ORACLE 8I后引入的許多新特性都必須在CBO下才能使用,而你的SQL語句可能正好使用了這些新特性,此時(shí)數(shù)據(jù)庫會(huì)自動(dòng)轉(zhuǎn)為使用CBO優(yōu)化器執(zhí)行這些語句。什么是優(yōu)化       優(yōu)化是選擇最有效的執(zhí)行計(jì)劃來執(zhí)行SQL語句的過程,這是在處理任何數(shù)據(jù)的語句(SELECT,INSERT,UPDATE或DELETE)中的一個(gè)重要步驟。對(duì)Oracle

64、來說,執(zhí)行這樣的語句有許多不同的方法,譬如說,將隨著以什么順序訪問哪些表或索引的不同而不同。所使用的執(zhí)行計(jì)劃可以決定語句能執(zhí)行得有多快。Oracle中稱之為優(yōu)化器(Optimizer)的組件用來選擇這種它認(rèn)為最有效的執(zhí)行計(jì)劃。       由于一系列因素都會(huì)會(huì)影響語句的執(zhí)行,優(yōu)化器綜合權(quán)衡各個(gè)因素,在眾多的執(zhí)行計(jì)劃中選擇認(rèn)為是最佳的執(zhí)行計(jì)劃。然而,應(yīng)用設(shè)計(jì)人員通常比優(yōu)化器更知道關(guān)于特定應(yīng)用的數(shù)據(jù)特點(diǎn)。無論優(yōu)化器多么智能,在某些情況下開發(fā)人員能選擇出比優(yōu)化器選擇的最優(yōu)執(zhí)行計(jì)劃還要好的執(zhí)行計(jì)劃。這是需要人工干預(yù)數(shù)據(jù)庫優(yōu)化的主要原因。事實(shí)表明,在某些情況下,確

65、實(shí)需要DBA對(duì)某些語句進(jìn)行手工優(yōu)化。注:從Oracle的一個(gè)版本到另一個(gè)版本,優(yōu)化器可能對(duì)同一語句生成不同的執(zhí)行計(jì)劃。在將來的Oracle 版本中,優(yōu)化器可能會(huì)基于它可以用的更好、更理想的信息,作出更優(yōu)的決策,從而導(dǎo)致為語句產(chǎn)生更優(yōu)的執(zhí)行計(jì)劃。   第5章 ORACLE的執(zhí)行計(jì)劃背景知識(shí):        為了更好的進(jìn)行下面的內(nèi)容我們必須了解一些概念性的術(shù)語:共享sql語句    為了不重復(fù)解析相同的SQL語句(因?yàn)榻馕霾僮鞅容^費(fèi)資源,會(huì)導(dǎo)致性能下降),在第一次解析之后,ORACLE將SQL語句及解析后得到

66、的執(zhí)行計(jì)劃存放在內(nèi)存中。這塊位于系統(tǒng)全局區(qū)域SGA(system global area)的共享池(shared buffer pool)中的內(nèi)存可以被所有的數(shù)據(jù)庫用戶共享。因此,當(dāng)你執(zhí)行一個(gè)SQL語句(有時(shí)被稱為一個(gè)游標(biāo))時(shí),如果該語句和之前的執(zhí)行過的某一語句完全相同,并且之前執(zhí)行的該語句與其執(zhí)行計(jì)劃仍然在內(nèi)存中存在,則ORACLE就不需要再進(jìn)行分析(指的是執(zhí)行計(jì)劃的選擇過程,至于語法檢查、對(duì)象和權(quán)限確認(rèn)還是會(huì)做的吧?),直接得到該語句的執(zhí)行路徑。ORACLE的這個(gè)功能大大地提高了SQL的執(zhí)行性能并大大節(jié)省了內(nèi)存的使用。使用這個(gè)功能的關(guān)鍵是將執(zhí)行過的語句盡可能放到內(nèi)存中,所以這要求有大的共享

67、池(通過設(shè)置shared buffer pool參數(shù)值)和盡可能的使用綁定變量的方法執(zhí)行SQL語句。    當(dāng)你向ORACLE 提交一個(gè)SQL語句,ORACLE會(huì)首先在共享內(nèi)存中查找是否有相同的語句。這里需要注明的是,ORACLE對(duì)兩者采取的是一種嚴(yán)格匹配,要達(dá)成共享,SQL語句必須完全相同(包括空格,換行等)。    下面是判斷SQL語句是否與共享內(nèi)存中某一SQL相同的步驟: 1). 對(duì)所發(fā)出語句的文本串進(jìn)行hashed。如果hash值與已在共享池中SQL語句的hash值相同,則進(jìn)行第2步:(hash值相同,語句到不一定相同,還需要具體確認(rèn)) 

68、;       2)將所發(fā)出語句的文本串(包括大小寫、空白和注釋)與在第步中識(shí)別的所有已存在的SQL語句相比較。        例如:        SELECT * FROM emp WHERE empno = 1000;         和下列每一個(gè)都不同         SELECT * from emp WHERE empno = 1000;     

69、;   SELECT * FROM EMP WHERE empno = 1000;        SELECT * FROM emp WHERE empno = 2000;        在上面的語句中列值都是直接SQL語句中的,今后我們將這類sql成為硬編碼SQL或字面值SQL                使用綁定變量的SQL語句中必須使用相同的名字的綁定變量(bind variables) ,例如: 

70、        a. 該2個(gè)sql語句被認(rèn)為相同        select pin , name from people where pin = :blk1.pin;         select pin , name from people where pin = :blk1.pin;         b. 該2個(gè)sql語句被認(rèn)為不相同        select pin

71、, name from people where pin = :blk1.ot_ind;         select pin , name from people where pin = :blk1.ov_ind;         今后我們將上面的這類語句稱為綁定變量SQL。        3). 將所發(fā)出語句中涉及的對(duì)象與第步中識(shí)別的已存在語句所涉及對(duì)象(使用對(duì)象的全稱,加上模式名)相比較。           例如:            如用戶user1與用戶user2下都有EMP表,則           用戶us

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論