oracle 數(shù)據(jù)庫sql調(diào)優(yōu)_第1頁
oracle 數(shù)據(jù)庫sql調(diào)優(yōu)_第2頁
oracle 數(shù)據(jù)庫sql調(diào)優(yōu)_第3頁
oracle 數(shù)據(jù)庫sql調(diào)優(yōu)_第4頁
oracle 數(shù)據(jù)庫sql調(diào)優(yōu)_第5頁
已閱讀5頁,還剩2頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、Oracle數(shù)據(jù)庫性能優(yōu)化(SQL調(diào)優(yōu)篇)引言對于數(shù)據(jù)庫系統(tǒng)來說,優(yōu)化是一件非常重要而且煩瑣的工作。通過優(yōu)化我們可以大大的提高系統(tǒng)運行效率和存儲空間的利用率,達(dá)到用有限的資源實現(xiàn)一個高效的應(yīng)用系統(tǒng);說它煩瑣是因為它涉及的面太寬了,從系統(tǒng)的規(guī)劃、庫表的設(shè)計、sql語句的編寫、物理設(shè)備和網(wǎng)絡(luò)設(shè)備的性能、內(nèi)存和存儲空間的分配等等都影響著系統(tǒng)的性能。正因為它的煩瑣,才給系統(tǒng)優(yōu)化工作者們提供了一個施展才華的舞臺。對于sql是一個基礎(chǔ)簡單卻有是較難寫好的查詢語言,它的好壞直接影響系統(tǒng)的性能;本篇將從sql查詢的內(nèi)部原理、oracle數(shù)據(jù)庫服務(wù)器是怎么處理sql的、oracle數(shù)據(jù)庫sql優(yōu)化原則、orac

2、le sql怎么優(yōu)化,對于sql怎樣使用就沒有作說明。Sql查詢內(nèi)部原理查詢在處理過程中分為四個大的階段:將查詢轉(zhuǎn)換為內(nèi)部格式階段、將內(nèi)部格式轉(zhuǎn)換為規(guī)范格式階段、為執(zhí)行選擇低層過程階段、生成并選擇最低的查詢計劃階段,如圖:目錄表源查詢DML處理器編譯后查詢元數(shù)據(jù)結(jié)果源查詢查詢計劃運行時管理器優(yōu)化器數(shù)據(jù)庫編譯視圖處理翻譯關(guān)系代數(shù)表達(dá)式表達(dá)式轉(zhuǎn)換代價估算優(yōu)化后的代碼執(zhí)行階段1:將查詢轉(zhuǎn)換為內(nèi)部格式階段這一階段主要是進(jìn)行語法分析,將原查詢轉(zhuǎn)換為數(shù)據(jù)庫內(nèi)部格式以便于機器處理,不符合語法規(guī)范的報錯返回,為sql優(yōu)化過程鋪平道路。階段2:將內(nèi)部格式轉(zhuǎn)換為規(guī)范格式在這一階段,數(shù)據(jù)庫優(yōu)化器將執(zhí)行一系列“保證能

3、夠優(yōu)化”的優(yōu)化過程,是不會去考慮實際數(shù)據(jù)的值和數(shù)據(jù)庫的存取路徑;優(yōu)化器將查詢的內(nèi)部表示轉(zhuǎn)換為等價的規(guī)范格式。比如說將“A=B替換為B=A或者是p and q 替換為q and p”,這樣做的目的是消除語句表面上的差異,以便能夠找到一種在某些方面比原查詢更為高效的表示方法。比如說能夠?qū)⒈磉_(dá)式(A JOIN B)WHERE retriction on A 轉(zhuǎn)為等價高效的表達(dá)式(A WHERE restriction on A)JOIN B。階段3:為執(zhí)行選擇低層過程在這一階段,優(yōu)化器考慮的是索引、物理存取路徑、數(shù)據(jù)值的分布、數(shù)據(jù)的物理聚集存儲等問題。基本的策略就是將查詢表達(dá)式看成一系列的“低層操作

4、”,對于每一個可能的低層操作,都有一組可用的低層過程,而每一個低層過程都會有一個相關(guān)的代價計算公式(磁盤i/o代價,cpu利用率)。階段4:生成并選擇最低代價的查詢計劃這一階段就是構(gòu)造一組查詢計劃,選擇一個最優(yōu),也就是代價最小的查詢計劃。因為每個計劃都綁定一系列的低層過程,每一個過程對應(yīng)查詢中的一個低層操作。優(yōu)化器此時將所有的過程進(jìn)行計算,選擇一個代價最低的執(zhí)行。那么oracle 又是怎么來處理sql的呢?我們來看看:oracle分析處理sql的簡單過程oracle在處理SQL語句上我們簡單的概括為的三個階段:語法分析、OK用戶進(jìn)程服務(wù)器進(jìn)程解析StatementOKHandle執(zhí)行Handl

5、e提取Results執(zhí)行、 返回指令(如圖)Select 過程:用戶select查詢語句發(fā)送至server,server在共享池進(jìn)行語法分析和生成執(zhí)行計劃,然后由后臺專有server從磁盤讀取數(shù)據(jù)到data buffer,并且返回給用戶,整個過程如圖:Server共享池數(shù)據(jù)緩沖區(qū)SGAUserUserUserB1B2EMP TableBlock 1Block2UPDATE操作過程:為了支持讀一致性,恢復(fù)和回滾,所有修改操作需要回滾段。修改操作執(zhí)行:(1)將數(shù)據(jù)塊送到數(shù)據(jù)緩沖區(qū)(2)將回滾塊送到數(shù)據(jù)緩沖區(qū)(3)在修改行上設(shè)置行鎖(4)保存回滾數(shù)據(jù)到回滾段塊(5) 將修改寫到數(shù)據(jù)塊Update、s

6、elect在oracle并行處理:如圖Server1UserUserUser1Server2UserUserUser2共享池數(shù)據(jù)緩沖區(qū)SGAB1B2R2R1EMP TableBlock 1Block2RB01R1R2Data File 1Data File 2 Insert 和delete操作和update類似,這里不作論述。我們在對查詢的原理、oracle內(nèi)部查詢機制作了一些簡單討論后,我們現(xiàn)在開始討論oracle 的sql優(yōu)化:oracle sql優(yōu)化原則Oracle 的 SQL 調(diào)優(yōu)是一個非常復(fù)雜的主題,可以豪不夸張的說需要一本書的內(nèi)容來介紹 Oracle SQL 調(diào)優(yōu)的細(xì)微差別。不過有

7、一些基本的規(guī)則是我們每個開發(fā)人員都需要跟從的,這些規(guī)則可以改善我們系統(tǒng)的性能。oracle sql優(yōu)化的原則是:消除不必要的大表全表搜索、最優(yōu)的索引使用、最優(yōu)的 JOIN 操作。消除不必要的大表全表搜索:不必要的全表搜索導(dǎo)致大量不必要的 I/O ,從而拖慢整個數(shù)據(jù)庫的性能。調(diào)優(yōu)專家首先會根據(jù)查詢返回的行數(shù)目來評價 SQL 。在一個有序的表中,如果查詢返回少于 40% 的行,或者在一個無序的表中,返回少于 7% 的行,那么這個查詢都可以調(diào)整為使用一個索引來代替全表搜索。對于不必要的全表搜索來說,最常見的調(diào)優(yōu)方法是增加索引??梢栽诒碇屑尤霕?biāo)準(zhǔn)的 B 樹索引,也可以加入 bitmap 和基于函數(shù)的索

8、引。要決定是否消除一個全表搜索,你可以仔細(xì)檢查索引搜索的 I/O 開銷和全表搜索的開銷,它們的開銷和數(shù)據(jù)塊的讀取和可能的并行執(zhí)行有關(guān),并將兩者作對比。在一些情況下,一些不必要的全表搜索的消除可以通過強制使用一個 index 來達(dá)到,只需要在 SQL 語句中加入一個索引的提示就可以了。確保最優(yōu)的索引使用 :對于改善查詢的速度,這是特別重要的。有時 Oracle 可以選擇多個索引來進(jìn)行查詢,調(diào)優(yōu)專家必須檢查每個索引并且確保 Oracle 使用正確的索引。它還包括 bitmap 和基于函數(shù)的索引的使用。 確保最優(yōu)的 JOIN 操作:有些查詢使用 NESTED LOOP join 快一些,有些則是 H

9、ASH join 快一些,另外一些則是 sort-merge join 更快。 這些規(guī)則看來簡單,不過它們占 SQL 調(diào)優(yōu)任務(wù)的 90% ,并且它們也無需完全懂得 Oracle SQL 的內(nèi)部運作。以下我們來簡單概覽以下 Oracle SQL 的優(yōu)化。oracle sql優(yōu)化我們首先簡要查看 Oracle 的排序,并且看一看排序操作是如何影響性能的。 調(diào)整 Oracle 的排序操作 排序是 SQL 語法中一個小的方面,但很重要,在 Oracle 的調(diào)整中,它常常被忽略。當(dāng)使用 create index 、 ORDER BY 或者 GROUP BY 的語句時, Oracle 數(shù)據(jù)庫將會自動執(zhí)行排

10、序的操作。通常,在以下的情況下 Oracle 會進(jìn)行排序的操作:使用 Order by 的 SQL 語句、使用 Group by 的 SQL 語句、在創(chuàng)建索引的時候 、進(jìn)行 table join 時。當(dāng)與 Oracle 建立起一個 session 時,在內(nèi)存中就會為該 session 分配一個私有的排序區(qū)域。如果該連接是一個專用的連接 (dedicated connection) ,那么就會根據(jù) init.ora 中 sort_area_size 參數(shù)的大小在內(nèi)存中分配一個 Program Global Area (PGA) 。如果連接是通過多線程服務(wù)器建立的,那么排序的空間就在 large_

11、pool 中分配。不幸的是,對于所有的 session ,用做排序的內(nèi)存量都必須是一樣的,我們不能為需要更大排序的操作分配額外的排序區(qū)域。因此,設(shè)計者必須作出一個平衡,在分配足夠的排序區(qū)域以避免發(fā)生大的排序任務(wù)時出現(xiàn)磁盤排序( disk sorts )的同時,對于那些并不需要進(jìn)行很大排序的任務(wù),就會出現(xiàn)一些浪費。當(dāng)然,當(dāng)排序的空間需求超出了 sort_area_size 的大小時,這時將會在 TEMP 表空間中分頁進(jìn)行磁盤排序。磁盤排序要比內(nèi)存排序大概慢 14,000 倍。上面我們已經(jīng)提到,私有排序區(qū)域的大小是有 init.ora 中的 sort_area_size 參數(shù)決定的。每個排序所占用

12、的大小由 init.ora 中的 sort_area_retained_size 參數(shù)決定。當(dāng)排序不能在分配的空間中完成時,就會使用磁盤排序的方式,即在 Oracle 實例中的臨時表空間中進(jìn)行。磁盤排序的開銷是很大的,有幾個方面的原因。首先,和內(nèi)存排序相比較,它們特別慢;而且磁盤排序會消耗臨時表空間中的資源。Oracle 還必須分配緩沖池塊來保持臨時表空間中的塊。無論什么時候,內(nèi)存排序都比磁盤排序好,磁盤排序?qū)钊蝿?wù)變慢,并且會影響 Oracle 實例的當(dāng)前任務(wù)的執(zhí)行。還有,過多的磁盤排序?qū)?free buffer waits 的值變高,從而令其它任務(wù)的數(shù)據(jù)塊由緩沖中移走。 接著,讓我們

13、看一下 Oracle 的競爭,并且看一下表的存儲參數(shù)的設(shè)置是如何影響 SQL UPDATE 和 INSERT 語句的性能的。 調(diào)整 Oracle 的競爭 Oracle 的其中一個優(yōu)點是它可以管理每個表空間中的自由空間。 Oracle 負(fù)責(zé)處理表和索引的空間管理,這樣就可以讓我們無需懂得 Oracle 的表和索引的內(nèi)部運作。不過,對于有經(jīng)驗的 Oracle 調(diào)優(yōu)專家來說,他需要懂得 Oracle 是如何管理表的 extent 和空閑的數(shù)據(jù)塊。對于調(diào)整擁有高的 insert 或者 update 的系統(tǒng)來說,這是非常重要的。要精通對象的調(diào)整,你需要懂得 freelists 和 freelist 組的

14、行為,它們和 pctfree 及 pctused 參數(shù)的值有關(guān)。這些知識對于企業(yè)資源計劃( ERP )的應(yīng)用是特別重要的,因為在這些應(yīng)用中,不正確的表設(shè)置通常是 DML 語句執(zhí)行慢的原因。 對于初學(xué)者來說,最常見的錯誤是認(rèn)為默認(rèn)的 Oracle 參數(shù)對于所有的對象都是最佳的。除非磁盤的消耗不是一個問題,否則在設(shè)置表的 pctfree 和 pctused 參數(shù)時,就必須考慮平均的行長和數(shù)據(jù)庫的塊大小,這樣空的塊才會被有效地放到 freelists 中。當(dāng)這些設(shè)置不正確時,那些得到的 freelists 也是 "dead" 塊,因為它們沒有足夠的空間來存儲一行,這樣將會導(dǎo)致明顯

15、的處理延遲。 Freelists 對于有效地重新使用 Oracle 表空間中的空間是很重要的,它和 pctfree 及 pctused 這兩個存儲參數(shù)的設(shè)置直接相關(guān)。通過將 pctused 設(shè)置為一個高的值,這時數(shù)據(jù)庫就會盡快地重新使用塊。不過,高性能和有效地重新使用表的塊是對立的。在調(diào)整 Oracle 的表格和索引時,需要認(rèn)真考慮究竟需要高性能還是有效的空間重用,并且據(jù)此來設(shè)置表的參數(shù)。以下我們來看一下這些 freelists 是如何影響 Oracle 的性能的。 當(dāng)有一個請求需要插入一行到表格中時, Oracle 就會到 freelist 中尋找一個有足夠的空間來容納一行的塊。你也許知道,

16、 freelist 串是放在表格或者索引的第一個塊中,這個塊也被稱為段頭( segment header )。 pctfree 和 pctused 參數(shù)的唯一目的就是為了控制塊如何在 freelists 中進(jìn)出。雖然 freelist link 和 unlink 是簡單的 Oracle 功能,不過設(shè)置 freelist link (pctused) 和 unlink (pctfree) 對 Oracle 的性能確實有影響。由DBA 的基本知識知道, pctfree 參數(shù)是控制 freelist un-links 的(即將塊由 freelists 中移除)。設(shè)置 pctfree=10 意味著每個

17、塊都保留 10% 的空間用作行擴(kuò)展。 pctused 參數(shù)是控制 freelist re-links 的。設(shè)置 pctused=40 意味著只有在塊的使用低于 40% 時才會回到表格的 freelists 中。許多新手對于一個塊重新回到 freelists 后的處理都有些誤解。其實,一旦由于一個刪除的操作而令塊被重新加入到 freelist 中,它將會一直保留在 freelist 中即使空間的使用超過了 60% ,只有在到達(dá) pctfree 時才會將數(shù)據(jù)塊由 freelist 中移走。表格和索引存儲參數(shù)設(shè)置的要求總結(jié) 以下的一些規(guī)則是用來設(shè)置 freelists, freelist group

18、s, pctfree 和 pctused 存儲參數(shù)的。你也知道, pctused 和 pctfree 的值是可以很容易地通過 alter table 命令修改的,一個好的 DBA 應(yīng)該知道如何設(shè)置這些參數(shù)的最佳值。 有效地使用空間和高性能之間是有矛盾的,而表格的存儲參數(shù)就是控制這個方面的矛盾:對于需要有效地重新使用空間,可以設(shè)置一個高的 pctused 值,不過副作用是需要額外的 I/O 。一個高的 pctused 值意味著相對滿的塊都會放到 freelist 中。因此,這些塊在再次滿之前只可以接受幾行記錄,從而導(dǎo)致更多的 I/O 。追求高性能的話,可以將 pctused 設(shè)置為一個低的值,這

19、意味著 Oracle 不會將數(shù)據(jù)塊放到 freelists 中直到它幾乎是空的。那么塊將可以在滿之前接收更多的行,因此可以減少插入操作的 I/O 。要記住 Oracle 擴(kuò)展新塊的性能要比重新使用現(xiàn)有的塊高。對于 Oracle 來說,擴(kuò)展一個表比管理 freelists 消耗更少的資源。 以上所論述的都是dba調(diào)優(yōu)時候要考慮的,那么我們的開發(fā)人員在寫sql的時候同樣對系統(tǒng)的優(yōu)化起著非常重要的影響,那我們現(xiàn)在就來談?wù)剆ql編寫的一般經(jīng)驗性原則:1. 選用適合的ORACLE優(yōu)化器:ORACLE的優(yōu)化器共有3種:a. RULE (基于規(guī)則) b. COST (基于成本) c. CHOOSE (選擇性

20、)。我們一般用choose(選擇性),可以避免全表掃描。2. 訪問Table的方式:全表掃描、通過ROWID訪問表。通過ROWID訪問表提高訪問表的效率,我們通常通過索引來實現(xiàn)這種方式。3. 共享SQL語句:為了不重復(fù)解析相同的SQL語句,在第一次解析之后, ORACLE將SQL語句存放在內(nèi)存中.這塊位于系統(tǒng)全局區(qū)域SGA(system global area)的共享池(shared buffer pool)中的內(nèi)存可以被所有的數(shù)據(jù)庫用戶共享。可以在init.ora中為這個區(qū)域設(shè)置合適的參數(shù),當(dāng)這個內(nèi)存區(qū)域越大,就可以保留更多的語句,當(dāng)然被共享的可能性也就越大了。4. 選擇最有效率的表名順序:

21、這種情況就要求編寫sql的開發(fā)人員要對表的數(shù)據(jù)的容量和表數(shù)據(jù)的增長速度有一個了解,通常情況是將小表放在前,大表放在后面。5. WHERE子句中的連接順序:ORACLE采用自下而上的順序解析WHERE子句,根據(jù)這個原理,表之間的連接必須寫在其他WHERE條件之前, 那些可以過濾掉最大數(shù)量記錄的條件必須寫在WHERE子句的末尾。6. SELECT子句中避免使用 * :因為ORACLE在解析的過程中, 會將'*' 依次轉(zhuǎn)換成所有的列名, 這個工作是通過查詢數(shù)據(jù)字典完成的, 這意味著將耗費更多的時間。7. 減少訪問數(shù)據(jù)庫的次數(shù):即是有些可以用簡單的一句sql就可以完成的不要寫成多句,或

22、者用一個游標(biāo)。8. 使用DECODE函數(shù)來減少處理時間:使用DECODE函數(shù)可以避免重復(fù)掃描相同記錄或重復(fù)連接相同的表。9. 整合簡單,無關(guān)聯(lián)的數(shù)據(jù)庫訪問:將簡單的多個查詢最好整合成一個查詢,這樣可以減少訪問數(shù)據(jù)庫的次數(shù)。10. 盡量多使用COMMIT:在存儲過程我們要多用它,這樣server可以快速釋放資源。11. 用Where子句替換HAVING子句:避免使用HAVING子句, HAVING 只會在檢索出所有記錄之后才對結(jié)果集進(jìn)行過濾. 這個處理需要排序,總計等操作. 如果能通過WHERE子句限制記錄的數(shù)目,那就能減少這方面的開銷。12. 使用表的別名(Alias):當(dāng)在SQL語句中連接多個表時, 請使用表的別名并把別名前綴于每個Column上.這樣一來,就可以減少解析的時間

溫馨提示

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

評論

0/150

提交評論