<轉>oracle效能調整讀書筆記(3)

wuhesheng發表於2009-07-16

第三章 SQL 調整 7.簇 o? { rPFR
b_xGCB C
· 簇是一個或多個表的組合,這些表的資料儲存在相同的資料塊中,當通過簇鍵查詢這些表時,只需讀一個資料塊就能返回連線的多個表的資料; cp g +-Zf%
· 有兩種簇,索引簇和雜湊簇; Y R }P ;
· 符合下面的條件時適合使用簇: A*_ |/o
Ø 表初始裝載以後,很少或者沒有DML發生; 3D/
Ø 針對每一條主表記錄,從表中的記錄數大致相同並且範圍可知; E3
Ø 更多地是對簇中的表一起查詢,較少單獨查詢(適於索引簇); y %^TZ[S
Ø 查詢WHERE條件中使用針對簇鍵的相等匹配(適於雜湊簇)。 8F*"z^ vD=
· 先建立簇,建簇時系統分配簇段,再在表建立時將表指定到簇,建表時不能指定表空間,所需空間從簇段中分配; w` ;>+_ E7
· 建簇時需指定簇鍵,不管有多個表或者多少條記錄,同一鍵值在簇中只儲存一次; ) @O KL 0t
· 建簇時指定SIZE關鍵值,這個值定義與一個簇鍵關聯的記錄佔用的空間之和; ' E#;`}&Ah
· 索引簇的關鍵字是INDEX(這是預設值),雜湊簇的關鍵字是HASHKEYS(這個子句後跟一個整數指定簇的雜湊值個數,雜湊值是簇鍵值通過簇雜湊函式計算後的返回值,雜湊值相同的行會一起儲存); u k )6%
· 索引簇在建簇後必須再建簇鍵欄位的索引,這時系統再分配一個索引段(不明白為什麼系統不把這兩步聯起來,而要這樣多此一舉?);雜湊簇上不能建針對簇鍵的索引; n :P 5 m9T
· 針對索引簇表的查詢和普通表相似,可能也是先索引再簇;針對雜湊簇表的查詢,如果WHERE條件中用到鍵欄位的相等匹配,用與插入時相同的雜湊演算法處理這個鍵值可以得出查詢資料的位置,只需一個IO即可取得需要的資料; 5QoU& H v
· 使用簇時必須小心規劃和測試,否則反而會給效能帶來負面影響。 V.k 2t$@
R:LT hFx
!U2 Wiks
第四章 調整共享池 1.理解共享池 EhBYmc" &
&o y j 8

理解共享池 lVmm`q 6n9
共享池是SGA的一部分,用來快取SQL和PL/SQL語句,共享池用LRU演算法來管理。 07? |"c.
B[I a8t
語句快取的好處 EZ.| 6oug\
· ORACLE執行SQL語句時,先將SQL語句的字串通過一個雜湊演算法得出一個雜湊值,然後檢查共享池中是否已存在這個雜湊值,若有就用已快取的執行計劃來執行這個語句(CACHE HIT 快取命中),若沒有(CACHE MISS 快取缺失)則需進行解析,解析需要完成下面的工作: Y l Y3C
Ø 語法檢查; jd &kak
Ø 語義檢查,看參考物件是否存在,型別是否正確; qOV 6Kh )
Ø (如果是CBO優化模式)收集參考物件的統計; B Aq@H8*B
Ø 檢查使用者的許可權是否足夠;
Ø 從許多可能的執行路徑中選擇一條作為執行計劃;
Ø 生成語句的編譯版本(P-CODE)。 vq df-i
· 解析是一個昂貴的操作,因為過程中需要消耗許多資源; s4$ Z.xwr
· 最大化CACHE HIT是調整共享池的目標 *o/ Q#
6o _t;c pT
共享池的元件 p ~T)Af
Library Cache (庫快取) !,#42 TY*X
· 庫快取用來存放最近執行過的SQL和PL/SQL(包括過程,函式,包,觸發器,匿名塊和JAVA類),包括以下元件:語句文字,雜湊值,P-CODE,相關的統計,執行計劃; X]? qn s7
· 與庫快取相關的動態效能檢視如下表: 7R 4 0t 3
檢視名 描述 8+Y+\X ZG
V$SQL 快取SQL的統計(IO,記憶體等),是根椐SQL文字和執行計劃來分組的 ZiB Te,;
V$SQLAREA 快取SQL的統計(IO,記憶體等),是根椐SQL文字來分組的 qwlIz/ j
V$SQLTEXT 快取SQL的完整文字,可能包括多行 ('/5#^% R
V$SQL_PLAN 快取SQL執行計劃的詳細內容,相同的SQL文字可能有不同的執行計劃 Rc2|o.'y
#]ZOi` ;
Data Dictionary Cache (資料字典快取) bg W= .s
· 在處理SQL或PL/SQL語句時,系統要檢查資料字典以確定需要的表是否存在,欄位名與資料型別是否正確,使用者是否有足夠的許可權,這部分資料快取在共享池的資料字典快取中,這塊記憶體區域同樣用LRU演算法來管理; V + /Vk1
· Oracle將資料字典快取與庫快取分開的原因是: W lHw\\ur
Ø 用與庫快取獨立的LRU演算法來管理字典資料,可以使得這部分資料在記憶體中保持更長的時間; ^ c1%$@ H
Ø 後續使用者發出與以前使用者類似的語句時,也能在資料字典快取中找到需要的資料。 &j } \Z D
2.=3:q!H
User Global Area (使用者全域性域) k~#F@_
· 只有在共享伺服器選項下,共享池中才存在UGA; A~u gx~S0
· UGA用來快取會話資訊(在共享伺服器選項下,一個會話的多條SQL或者PL/SQL語往往是由不同的伺服器程式來完成的,因此有必要將會話資訊存放在共享的位置;在專用伺服器配置下,使用者會話資訊存放在PGA中)。

第四章 調整共享池 2.測量共享池的效能 4J*% $Vx v
X_XeI!, b
&G ?b |Tb2
測量共享池的效能 s
· 共享池的效能主要用庫快取命中率和資料字典快取命中率來測量,前者更重要,Oracle建議在未調整好庫快取之前,不必費力去調整資料字典快取。 6JB E=9d-Q
B@dA ?w.x
測量庫快取的效能 : .Vn
· 庫快取的效能指標來自V$LIBRARYCACHE檢視,這個檢視的主要欄位描述如下: K:/%7A_{
欄位名 描述 可接受值(OLTP) E I6K0{'&X
NAMESPACE 主要的型別有SQL AREA (SQL語句), TABLE/PROCEDURE (儲存過程或函式), BODY (包體), TRIGGER (觸發器) 9r!psRA:`)
GETS 解析次數 z 7OTL
GETHITS 解析時發現語句的解析版本已存在於庫快取中(解析命中)的次數 GGsD R%U
GETHITRATIO 解析命中率 大於90% Au08 k}h
PINS 執行次數 Z? Y14 L~%
PINHITS 執行命中次數 V9f$ zjpw
PINHITRATIO 執行命中率 大於90% gt WJ R
RELOADS 重新解析的次數,重新解析的原因是已快取的解析版本老化或失效 sum(reloads)/sum(pins) < 1% chW 1UE
INVALIDATIONS 語句快取失效的次數,失效的原因是依賴物件被修改刪除或者編譯 4% )I[-sH
qB P UB (
· STATSPACK中存放關於庫快取效能的資料有兩個地方: T7_i: HU%
Ø Instance Efficiency Percentages (Target 100%)(例項命中率) – Library Hit %; [A99 e `
Ø Library Cache Activity for DB(庫快取活動)。 *^ +8_%; 1
fH[Y c>(oj
測量資料字典快取的效能 ak] :ir`o
· 資料字典快取效能指標來自V$ROWCACHE檢視,用下面的查詢來獲得命中率: *m H+ + 3h
select 1 – (sum(getmisses) / sum(gets)) from v$rowcache;可以接受的命中率是85%以上; ";\na !MT
· STATSPACK中關於資料字典快取效能的資料存放在Dictionary Cache Stats for DB(資料字典快取統計)。 YmXh_ bk
z&x ^ Dl
第四章 調整共享池 3.改進共享池的效能 ?86q8E3 ;&
H 4 l *
?Ybg zb
改進共享池的效能 P_Rh& gkuK
改進共享池的效能就是提高庫快取和資料字典快取的命中率,有以下一些方法: S3 Q^K.e?
)?es3Ehqq
增大共享池 1< 22,
· 增大共享池能減慢庫快取和資料字典快取被LRU演算法移出的速度,從而提高命中率; $Sz@u" ig%
· 庫快取命中率和資料字典快取命中率通常都趨向於一致,極少出現一高一低的情形; # !: u*1
· 共享池的大小由初始化引數SHARED_POOL_SIZE來確定; >uc VrLm,X
· 已使用庫快取的大小可以通過sum(V$DB_OBJECT_CACHE.SHARABLE_MEM)(非SQL物件)和 sum(V$SQLAREA.SHARABLE_MEM)(SQL語句) 來查詢; zVeQKN 9^Z
· 可以用ALTER SYSTEM SET SHARED_POOL_SIZE = XX; 來動態更改共享池的大小,但需保證更改後SGA的大小不大於SGA_MAX_SIZE,否則會現ORA-04033的錯誤; G3Z>,"w;=
· 也可以通過關機更改初始引數SHARED_POOL_SIZE再重啟來手工更改共享池的大小,這種方法適於同時改大SGA_MAX_SIZE這個引數; )1E[CIaXK
· 無統計資料時,可以按照下面的策略來為ORACLE伺服器分配記憶體: d'b AM {R>
Ø 作業系統(NT需要的較UNIX多),ORACLE後臺程式,伺服器程式,其它非ORACLE程式共需記憶體= 伺服器總記憶體 * 45%(1G以下時) or 25~40%(1G以上時); B4uJT ~,7>
Ø TSGA(SGA總記憶體) = 伺服器總記憶體 * 55%(1G以下時) or 60~75%(1G以上時); kK62y z ,
Ø TSGAI(單個例項的SGA記憶體) = TSGA / 伺服器上的例項數; n:T W Z.9
Ø 共享池 = TSGAI * 45%; 2 b&& 3u8
Ø 資料快取 = TSGAI * 45%; !L| }/u3 v
Ø 日誌快取 = TSGAI * 10% (10%的日誌快取通常都偏大,可待有統計資料後視情形將多出的部分分給共享池,資料快取或者大池); JI)@h 4b
Ø 若需配置大池和JAVA池時,從本例項SGA總記憶體中分配。 ygN4%- [XA
d _ [l{
為大的PL/SQL語句留空間; xJNV^u
· 執行大的PL/SQL程式時,為了獲得足夠的快取空間,LRU演算法會移出許多已解析的語句,爾後這些剛被移出的語句可能又要重新裝入,這樣就降低的庫快取的命中率,為了避免這樣的情形,可以設定共享池保留區給大的PL/SQL物件使用; ^yl)c \`
· 引數SHARED_POOL_RESERVED_SIZE用來指定共享池保留區的大小,最大可指定到共享池的一半,預設值是共享池的5%,ORACLE建議從共享池的10%開始調整; )XFaVkQ}
· 可以從V$DB_OBJECT_CACHE查到目前快取物件及其使用空間(OWNER, NAME, SHARABLE_MEM); *)8!~Hs
· 可以用V$SHARED_POOL_RESERVED檢視來監控保留區的使用情況以決定正確的保留區大小: =Z(_l LNmh
Ø REQUESTS 從保留區中請求空間的次數; VfFX H,j
Ø REQUEST_MISSES 保留區無空間可用而需要從非保留區清洗物件的請求次數;這個值為零或者一直很穩定表示保留區空間設定偏大; d#W>"Cqxqa
Ø FREE_SPACE 保留區未用的空間;這個空間大於保留區的一半時表示保留區空間設定偏大; 3~ ptD5@WF
Ø REQUEST_FAILURES 請求無法滿足,出現ORA-04031錯誤的次數; 這個值非零或者穩定增加時表示保留區太小; 0!5 w0^1
Ø 隱含引數_shared_pool_reserve_min_alloc(4400)確定請求保留區的起始大小; 4?c4GT9(6S
Ø 調整保留區的目標是使REQUEST_MISSES, REQUEST_FAILURES接近零。 XD8Q 2 un
· 可以用DBMS_SHARED_POOL.ABORT_REQUEST_THRESHOLD這個包過程設定一個閥值,大於這個值的庫快取請求將會失敗。 ej;\a :JL
S Kdh !*G
Keep PL/SQL py':U QS*q
· 將重用率高的PL/SQL程式碼KEEP在庫快取中可以提高命中率,這個過程又稱Pinning,由DBMS_SHARED_POOL.KEEP過程來完成,這些物件存放在共享池保留區中; y yqya[-11
· 清洗共享池語句(ALTER SYSTEM FLUSH SHARED_POOL;)並不會清洗Pinned物件,但是系統重啟後,這些物件將不再是Pinned。 ?(2^ lH~6h
· Keep相關: H"vy[/ UcR
Ø DBMS_SHARED_POOL這個包並沒有在執行catproc.sql時安裝,需執行一次dbmspool.sql這個指令碼; .DN)ck :e;
Ø 可以用這個包中的KEEP, UNKEEP來pin 和unpin儲存物件; 56l1&hp8In
Ø 可從V$DB_OBJECT_CACHE.KEEP這個欄位得知哪些物件已被Pinned。 +/|t8zFWs
· 要確定哪些物件適於KEEP,可以啟用審計功能來檢視是哪些物件被頻繁地呼叫,要KEEP匿名的PL/SQL程式比較麻煩,建議將經常使用且長度超過500個字元的匿名塊寫成過程和包再進行KEEP; UWIw/(Mv/]
· 因為重啟後所有的KEEP都將失效,所以將KEEP的動作放在系統觸發器中(AFTER STARTUP ON DATABASE)是較合適的。 $P bwC6>8
;'7 g g ]
程式碼重用; [~U CY Yl
· 確定是否需要對語句進行(硬)解析時,是先比較語句的雜湊值,下面的兩種方法有助於獲得相同的雜湊值,從而可以實現重用程式碼,提高命中率: sUTf Y|<7|
Ø 開發組的所有成員都使用相同的編碼規範(包括大小寫,空格,換行等); K'u66 %wAL
Ø 使用繫結變數(提高命中率的同時可能會產生不夠好的執行計劃,因為優化器不知道變數的確定值,在有欄位的柱狀圖統計資料時也不能夠利用)。 % 5r C`9 ^
ZT1I N6;8W
調整相關初始化引數。 Udl8?EV Sz
OPEN_CURSORS h&O8e;S #
· 這個引數指定每個使用者會話能開啟的遊標個數; CF0 i72ul5
· 增大這個值可以減少重新解析會話曾開啟的語句的機會,提高命中率,但需要更大的共享池空間。 R\^ XF8n6/
aZBb@~ Y
CURSOR_SPACE_FOR_TIME 2 9 ~Bu5
· 這個引數設為真時,只有當所有引用共享SQL的遊標都關閉後,LRU才有可能移出這個SQL所佔的快取空間來重用,預設值是FALSE; R} J}Q b
· 只有在共享池足夠大的情況下才能考慮設為真,設為真時可以減少重解析,提高命中率,加快遊標的執行(空間換時間)。 K% iA-h
dub %fs
SESSION_CACHED_CURSORS uqFY a b U
· 這個引數指定會話能夠快取遊標的個數,預設值是零; 7ElU5I
· 如果會話反覆執行某些語句,設定該值大於零能提高遊標的執行速度,這些快取也是用LRU演算法來管理的。 e_Un :r@)
IqrT@jgN-
CURSOR_SHARING i B0#Z _
· 這個引數決定什麼樣的SQL語句能夠共享遊標,有三個取值:FORCE, SIMILAR, EXACT; r>Rm=eK J
Ø FORCE 兩個語句的差異只在字面值,這些差異不會改變語句的含義時可共享遊標; =QQTH L{ 3
Ø SIMILAR兩個語句的差異只在字面值,這些差異不會改變語句的含義和執行計劃時可共享遊標(這個值是在9i 中引入,如果有差異的欄位上有柱狀圖統計,這時執行計劃會改變,不能共享遊標,行為同於EXACT,如果差異欄位上沒有柱狀圖統計,執行計劃相同,這時的行為同於FORCE); H68~5lJY^]
Ø EXACT 兩個語句必須精確匹配才能共享遊標,這是預設值。 ?vn9HhT D
7>,( QHl
8DL j?M >N
第五章 調整資料快取 1.理解資料快取 tkj QSz
[QZ g =. "
Q! *}^W
理解資料快取 J
· 資料快取是SGA的一部分,用於存放使用者最近存取過的段的資料塊的副本,這些段可能是資料段,索引段,簇段,LOB段,LOB索引段,回滾段,臨時段,資料快取單元的大小與資料庫塊大小一致。 [Zx v&$SQ
· 資料快取用下面的方法進行管理: w 8B SY
v 1O1 -aM
LRU列表 ?%A9}"q]
· 在Oracle執行SQL語句的過程中,相關的段資料要複製到SGA的資料快取中來,這個操作由使用者的伺服器程式來執行; .$ " 13"
· 與共享池類似,資料快取也是由LRU演算法來管理的,當資料快取的快取塊被填滿而又有新的快取塊請求時,LRU將最近最少使用的快取塊老化出去,而保留最近經常使用的快取塊,當一個使用者發現要讀取的資料塊已在之前由其它使用者讀入時,就可以節約很多時間,因為從記憶體中讀取比從磁碟中讀取要快上數千倍; +oev NM
· LRU演算法管理一個LRU列表,這個列表類似於一個輸送帶,伺服器程式將剛剛存取過的資料塊放在輸送帶的開始端,隨著更多的塊被讀入,先前讀入的塊向輸送帶末端移動,如果在到達末端之前某個塊被再一次存取,則這個塊又被移到開始端,否則就會從輸送帶末端跌落(快取塊被老化); P r qyJ
· LRU對全表掃描時讀入快取塊的管理與上面的有些不同,這些塊一讀入就被放在LRU列表的末端,這樣可以避免對大表全表掃描時把資料快取中的所有快取塊都清洗出去; c 4 V% >A
· LRU演算法管理下的快取塊有四種狀態: 8vqx} 2
Ø Free 自資料庫啟動以來尚未被使用過的快取塊; V jLv{f


Ø Pinned 正在被伺服器程式使用的快取塊; WCD)yTg:ES
Ø Clean 曾被使用過且可立即被重用的快取塊,讀入後未經修改或者最近一次修改已被寫回磁碟,快取版本與檔案資料塊一致; F}~ qTF;H
Ø Dirty 曾被使用過且不能立即被重用的快取塊,讀入後作過修改且最近一次修改未被寫回磁碟,快取版本與檔案資料塊不一致; {n\ Ai3F-
· 管理髒塊時會用到一個髒塊列表(Dirty List,又名寫列表),這個列表被檢查點佇列使用,用於跟蹤所有的髒塊,以第一次修改時間排序,髒塊由DBW0程式寫回磁碟。 U# Wg" W{
[\3 W_jR
使用者伺服器程式 e zb *tN!
· 當需要讀取某個資料塊時,伺服器程式先到資料快取中檢視該塊是否已存在,若沒有找到,就需要將資料塊從資料檔案讀到資料快取中來,這首先要在資料快取中找到一個可用的快取塊來容納資料塊的副本,這個過程中伺服器程式可能要和LRU列表以及髒列表打交道: ;,/4Ry22j-
Ø 在LRU列表上查詢可用塊的時候,伺服器程式將查到的髒塊從LRU列表移到髒列表; xz Hb+1+p
Ø 隨著髒塊的加入,髒列表不斷變長,當長度超過某個預定義的長度時,觸發DBW0將髒列表上的髒塊寫回磁碟; lK_T %1Gz
Ø 如果伺服器程式在LRU列表查詢很多的塊(超過某個閥值)都沒能找到可用的塊時,觸發DBW0程式,將髒塊直接從LRU列表寫回磁碟。 22 'Ra [
· 如果伺服器程式發現要找的塊已在資料快取中,但塊的版本要晚於一致性讀需要的版本時(版本更早時可直接使用),伺服器程式在資料快取中建立一個新塊利用回滾段資料回滾到需要的版本(如果是在序列化事務中,且造成更晚版本的已提交的修改不是由當前事務造成的話,則報錯)。 g /fr g(KF
x R 8y"CpE
資料庫寫入程式(DBW0) aJ@l T &.
· DBW0程式負責將資料快取中的髒塊寫回磁碟,這個操作在下面的情形下發生: ;d
Ø 伺服器程式不斷地將髒塊從LRU列表移到髒列表,當髒列表的長度達到閥值時,DBW0將髒列表上的髒塊寫回磁碟; # &e i
Ø 伺服器程式在LRU列表上檢查太多的塊都沒能找到一個可用塊的時候,DBW0直接從LRU列上將髒塊寫回磁碟; \u04m}h]
Ø DBW0程式每三秒被啟用一次,將LRU列表上的髒塊移到髒列表,若髒列表長度達到閥值時,從髒列表上將髒塊寫回磁碟; [nG[ x|;|
Ø 檢查點發生時,DBW0將髒塊從LRU列表移到髒列表,再從髒列表寫髒塊回磁碟; -g:i 'e
Ø 資料庫關閉時(不包括Shutdown Abort),DBW0將所有髒塊寫回磁碟; Nv| 0Z' M
Ø 表空間熱備前,DBW0將屬於這個表空間的所有髒塊從LRU列表移到髒列表,然後從髒列表將髒塊寫回磁碟; OsW * @v (
Ø 表空間離線時(Normal,Temporary),DBW0將屬於這個表空間的所有髒塊從LRU移到髒列表,然後從髒列表將髒塊寫回磁碟; P,b & F
Ø 刪除段時,DBW0先將這個段的髒塊寫回磁碟。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/119501/viewspace-609377/,如需轉載,請註明出處,否則將追究法律責任。

相關文章