


版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、人們在使用SQL時往往會陷入一個誤區(qū),即太關(guān)注于所得的結(jié)果是否正確,而忽略了不同的實現(xiàn)方法之間可能存在的性能差異,這種性能差異在大型的或是復(fù)雜的數(shù)據(jù)庫環(huán)境中(如聯(lián)機(jī)事務(wù)處理OLTP或決策支持系統(tǒng)DSS)中表現(xiàn)得尤為明顯。筆者在工作實踐中發(fā)現(xiàn),不良的SQL往往來自于不恰當(dāng)?shù)乃饕O(shè)計、不充份的連接條件和不可優(yōu)化的where子句。在對它們進(jìn)行適當(dāng)?shù)膬?yōu)化后,其運(yùn)行速度有了明顯地提高!下面我將從這三個方面分別進(jìn)行總結(jié): 為了更直觀地說明問題,所有實例中的SQL運(yùn)行時間均經(jīng)過測試,不超過秒的均表示為(< 1秒)。 測試環(huán)境· 主機(jī):HP LH II · 主頻:330MHZ
2、83; 內(nèi)存:128兆 · 操作系統(tǒng):Operserver5.0.4 · 數(shù)據(jù)庫:Sybase11.0.3 一、不合理的索引設(shè)計 例:表record有620000行,試看在不同的索引下,下面幾個SQL的運(yùn)行情況:1.在DATE上建有一個非群集索引 select count(*) from record where date > '19991201' and date < '19991214'and amount > 2000 (25秒) select date,sum(amount) from record group by
3、 date (55秒) select count(*) from record where date > '19990901' and place in ('BJ','SH') (27秒) 分析: date上有大量的重復(fù)值,在非群集索引下,數(shù)據(jù)在物理上隨機(jī)存放在數(shù)據(jù)頁上,在范圍查找時,必須執(zhí)行一次表掃描才能找到這一范圍內(nèi)的全部行。 2.在DATE上的一個群集索引 select count(*) from record where date > '19991201' and date < '19991214
4、' and amount > 2000 (14秒) select date,sum(amount) from record group by date (28秒) select count(*) from record where date > '19990901' and place in ('BJ','SH')(14秒) 分析: 在群集索引下,數(shù)據(jù)在物理上按順序在數(shù)據(jù)頁上,重復(fù)值也排列在一起,因而在范圍查找時,可以先找到這個范圍的起末點(diǎn),且只在這個范圍內(nèi)掃描數(shù)據(jù)頁,避免了大范圍掃描,提高了查詢速度。 3.在PLACE,DA
5、TE,AMOUNT上的組合索引 select count(*) from record where date > '19991201' and date < '19991214' and amount > 2000 (26秒) select date,sum(amount) from record group by date (27秒) select count(*) from record where date > '19990901' and place in ('BJ, 'SH')(<
6、1秒) 分析: 這是一個不很合理的組合索引,因為它的前導(dǎo)列是place,第一和第二條SQL沒有引用place,因此也沒有利用上索引;第三個SQL使用了place,且引用的所有列都包含在組合索引中,形成了索引覆蓋,所以它的速度是非??斓摹?4.在DATE,PLACE,AMOUNT上的組合索引 select count(*) from record where date > '19991201' and date < '19991214' and amount > 2000(< 1秒) select date,sum(amount) from
7、 record group by date (11秒) select count(*) from record where date > '19990901' and place in ('BJ','SH')(< 1秒) 分析: 這是一個合理的組合索引。它將date作為前導(dǎo)列,使每個SQL都可以利用索引,并且在第一和第三個SQL中形成了索引覆蓋,因而性能達(dá)到了最優(yōu)。 5.總結(jié): 缺省情況下建立的索引是非群集索引,但有時它并不是最佳的;合理的索引設(shè)計要建立在對各種查詢的分析和預(yù)測上。一般來說: · 有大量重復(fù)值、且經(jīng)常有范圍查
8、詢(between, >,< ,>=,< =)和order by 、group by發(fā)生的列,可考慮建立群集索引; · 經(jīng)常同時存取多列,且每列都含有重復(fù)值可考慮建立組合索引; · 組合索引要盡量使關(guān)鍵查詢形成索引覆蓋,其前導(dǎo)列一定是使用最頻繁的列。 二、不充份的連接條件: 例:表card有7896行,在card_no上有一個非聚集索引,表account有191122行,在 account_no上有一個非聚集索引,試看在不同的表連接條件下,兩個SQL的執(zhí)行情況: select sum(a.amount) from account a, card b
9、where a.card_no = b.card_no(20秒) 將SQL改為: select sum(a.amount) from account a, card b where a.card_no = b.card_no and a.account_no=b.account_no(< 1秒) 分析: 在第一個連接條件下,最佳查詢方案是將account作外層表,card作內(nèi)層表,利用card上的索引,其I/O次數(shù)可由以下公式估算為: 外層表account上的22541頁+(外層表account的191122行*內(nèi)層表card上對應(yīng)外層表第一行所要查找的3頁)=595907 次I/O 在
10、第二個連接條件下,最佳查詢方案是將card作外層表,account作內(nèi)層表,利用account上的索引,其I/O次數(shù)可由以下公式估算為: 外層表card上的1944頁+(外層表card的7896行*內(nèi)層表account上對應(yīng)外層表每一行所要查找的4頁)= 33528次I/O 可見,只有充份的連接條件,真正的最佳方案才會被執(zhí)行。 總結(jié): 1.多表操作在被實際執(zhí)行前,查詢優(yōu)化器會根據(jù)連接條件,列出幾組可能的連接方案并從中找出系統(tǒng)開銷最小的最佳方案。連接條件要充份考慮帶有索引的表、行數(shù)多的表;內(nèi)外表的選擇可由公式:外層表中的匹配行數(shù)*內(nèi)層表中每一次查找的次數(shù)確定,乘積最小為最佳方案。 2.查看執(zhí)行方
11、案的方法- 用set explain on,打開explain選項,就可以看到連接順序、使用何種索引的信息。 三、不可優(yōu)化的where子句 1.例:下列SQL條件語句中的列都建有恰當(dāng)?shù)乃饕?,但?zhí)行速度卻非常慢:select * from record where substring(card_no,1,4)='5378'(13秒) select * from record where amount/30< 1000(11秒) select * from record where convert(char(10),date,112)='19991201'(1
12、0秒) 分析: where子句中對列的任何操作結(jié)果都是在SQL運(yùn)行時逐列計算得到的,因此它不得不進(jìn)行表搜索,而沒有使用該列上面的索引;如果這些結(jié)果在查詢編譯時就能得到,那么就可以被SQL優(yōu)化器優(yōu)化,使用索引,避免表搜索,因此將SQL重寫成下面這樣: select * from record where card_no like '5378%'(< 1秒) select * from record where amount < 1000*30(< 1秒) select * from record where date= '1999/12/01'
13、(< 1秒) 你會發(fā)現(xiàn)SQL明顯快起來! 2.例:表STUFF有200000行,ID_NO上有非群集索引,請看下面這個SQL: select count(*) from stuff where id_no in('0','1') (23秒) 分析: where條件中的'in'在邏輯上相當(dāng)于'or',所以語法分析器會將in ('0','1')轉(zhuǎn)化為id_no ='0' or id_no='1'來執(zhí)行。我們期望它會根據(jù)每個or子句分別查找,再將結(jié)果相加,這樣可以利用
14、id_no上的索引;但實際上(根據(jù)explain),它卻采用了"OR策略",即先取出滿足每個or子句的行,存入臨時數(shù)據(jù)庫的工作表中,再建立唯一索引以去掉重復(fù)行,最后從這個臨時表中計算結(jié)果。因此,實際過程沒有利用id_no上索引,并且完成時間還要受tempdb數(shù)據(jù)庫性能的影響。 實踐證明,表的行數(shù)越多,工作表的性能就越差,當(dāng)stuff有620000行時,執(zhí)行時間竟達(dá)到220秒!還不如將or子句分開: select count(*) from stuff where id_no='0' select count(*) from stuff where id_no
15、='1' 得到兩個結(jié)果,再作一次加法合算。因為每句都使用了索引,執(zhí)行時間只有3秒,在620000行下,時間也只有4秒?;蛘?,用更好的方法,寫一個簡單的存儲過程: create proc count_stuff as declare a int declare b int declare c int declare d char(10) begin select a=count(*) from stuff where id_no='0' select b=count(*) from stuff where id_no='1' end select
16、c=a+b select d=convert(char(10),c) print d 直接算出結(jié)果,執(zhí)行時間同上面一樣快! 總結(jié): 可見,所謂優(yōu)化即where子句利用了索引,不可優(yōu)化即發(fā)生了表掃描或額外開銷。 1.任何對列的操作都將導(dǎo)致表掃描,它包括數(shù)據(jù)庫函數(shù)、計算表達(dá)式等等,查詢時要盡可能將操作移至等號右邊。 2.in、or子句常會使用工作表,使索引失效;如果不產(chǎn)生大量重復(fù)值,可以考慮把子句拆開;拆開的子句中應(yīng)該包含 索引。 3.要善于使用存儲過程,它使SQL變得更加靈活和高效。 從以上這些例子可以看出,SQL優(yōu)化的實質(zhì)就是在結(jié)果正確的前提下,用優(yōu)化器可以識別的語句,充份利用索引,減少表掃描
17、的I/O次數(shù),盡量避免表搜索的發(fā)生。其實SQL的性能優(yōu)化是一個復(fù)雜的過程,上述這些只是在應(yīng)用層次的一種體現(xiàn),深入研究還會涉及數(shù)據(jù)庫層的資源配置、網(wǎng)絡(luò)層的流量控制以及操作系統(tǒng)層的總體設(shè)計。 1. 監(jiān)控8s 數(shù)據(jù)庫性能簡介不少書籍和文章都對8s數(shù)據(jù)庫及其體系結(jié)構(gòu)和性能調(diào)優(yōu)進(jìn)行了詳盡論述,但專門討論監(jiān)控這一主題的卻很少。但在8s 數(shù)據(jù)庫管理中有效的監(jiān)控卻至關(guān)重要。它能幫助我們收集系統(tǒng)和數(shù)據(jù)庫性能方面有價值的統(tǒng)計信息,還能幫助我們很早就確定問題,以便我們能夠在故障診斷和性能調(diào)優(yōu)方面取得主動。在成功地安裝和配置 8s數(shù)據(jù)庫并實現(xiàn)了數(shù)據(jù)庫以后,對其進(jìn)行監(jiān)控就成為了數(shù)據(jù)庫管理員的頭等大事。監(jiān)控工具GBase
18、8s提供了兩個主要的工具來監(jiān)控系統(tǒng)和數(shù)據(jù)庫性能:· onstat實用程序 · sysmaster數(shù)據(jù)庫中眾多的系統(tǒng)監(jiān)控接口(SMI)表,該數(shù)據(jù)庫是在8s 數(shù)據(jù)庫 首次初始化時自動創(chuàng)建的 onstat實用程序和SMI 表都通過檢查 8s 數(shù)據(jù)庫 共享內(nèi)存活動來監(jiān)控 8s 數(shù)據(jù)庫 性能,但它們給出那些統(tǒng)計信息的方式卻有所不同。onstat 實用程序總是以固定的方式給出統(tǒng)計信息,而使用 SMI 表則允許您以更有意義、更可讀的格式重新組織那些統(tǒng)計信息。需要注意的一點(diǎn)是,無論是通過 onstat 收集還是在 SMI 表中收集,這些統(tǒng)計信息都是從系統(tǒng)重新引導(dǎo)或 8s 數(shù)據(jù)庫 初始化開始
19、累積而來的。因此,對于那些統(tǒng)計信息我們必須格外小心,并且總是要考慮 8s 數(shù)據(jù)庫 運(yùn)行時間。例如,服務(wù)器運(yùn)行超過一個月所累積的 100000 條 bufwait 與一天所累積的 100000 條 bufwait 就完全不同。要獲取當(dāng)前的統(tǒng)計信息,我們必須執(zhí)行 onstat -z 以清除舊值。8s數(shù)據(jù)庫活動可以分為三類: · 實例活動 · 數(shù)據(jù)庫活動 · 會話活動 通過使用上面討論的工具,我們可以有效地監(jiān)控所有那些 8s 數(shù)據(jù)庫 活動。監(jiān)控實例活動8s 數(shù)據(jù)庫 實例是指共享內(nèi)存、處理器、數(shù)據(jù)庫以及分配給數(shù)據(jù)庫的物理設(shè)備。以下是部分需要監(jiān)控的最重要的實例活動。操作方式
20、第一個也是最重要的實例活動當(dāng)然是 8s 數(shù)據(jù)庫 的操作方式。 8s 數(shù)據(jù)庫 運(yùn)行正常還是有問題,或是已當(dāng)機(jī)了?onstat -p 命令捕獲了 8s 數(shù)據(jù)庫 的當(dāng)前操作方式,如下所示:Profiledskreads pagreads bufreads %cached dskwrits pagwrits bufwrits %cached86923 101304 3116565 97.21 1651 15022 26196 93.70 isamtot open start read write rewrite delete commit rollbk2585879 118500 286631 103
21、2967 1972 914 2 2 0gp_read gp_write gp_rewrt gp_del gp_alloc gp_free gp_curs 0 0 0 0 0 0 0 ovlock ovuserthread ovbuff usercpu syscpu numckpts flushes 0 0 0 478.11 71.63 13 26 bufwaits lokwaits lockreqs deadlks dltouts ckpwaits compress seqscans3502 0 7065882 0 0 0 1266 11280 ixda-RA idx-RA da-RA RA-
22、pgsused lchwaits10120 51 69387 79557 482 我們也可以查詢 sysmaster 數(shù)據(jù)庫中的 sysprofile 表來獲取同樣的統(tǒng)計信息。輸出的第一行顯示了當(dāng)前的 8s 數(shù)據(jù)庫 操作方式。本例中,8s 引擎是"On-Line"??偣灿辛N操作方式,其中三種特別重要:Off-Line、Quiescent 和 On-Line。Off-Line 方式表明 8s 數(shù)據(jù)庫 當(dāng)前沒有在運(yùn)行。Quiescent 方式表明 8s 數(shù)據(jù)庫 正在以單用戶方式運(yùn)行,在這種方式下,只有 DBA 可以進(jìn)行管理和維護(hù)工作。On-Line 方式表明 8s 數(shù)據(jù)庫 正
23、在正常運(yùn)行,所有用戶都可以連接到數(shù)據(jù)庫服務(wù)器,并可以執(zhí)行各種數(shù)據(jù)庫操作。在大多數(shù)情況下, 8s 數(shù)據(jù)庫 應(yīng)該始終處于 On-Line 方式。如果因為種種原因 8s 數(shù)據(jù)庫 當(dāng)機(jī)了或處于 Off-Line 方式,那么上面的命令將顯示下面的消息:Shared memory not initialized for GBASEDBTSERVER 'cassprod_shm'在這種情況下,您需要檢查消息日志或 8s聯(lián)機(jī)日志,以進(jìn)一步確定問題的根源(請參閱消息日志)。除了當(dāng)前的操作方式以外,上面的輸出還提供了一些重要的8s實例性能統(tǒng)計信息。兩個 %cache 字段表明 8s 數(shù)據(jù)庫 目前使
24、用內(nèi)存高速緩存的效率。第一個 %cache 字段顯示了讀高速緩存比例的百分比,而第二個則顯示了寫高速緩存比例。讀高速緩存比例和寫高速緩存比例會隨應(yīng)用程序及正在操作的數(shù)據(jù)的類型和大小而動態(tài)變化。但讀高速緩存比例和寫高速緩存比例一般都應(yīng)該在 80 到 90 個百分點(diǎn)之間。這是十分保守的數(shù)字,應(yīng)該根據(jù)具體環(huán)境加以調(diào)整。如果這些比例始終低于 80%,那么您需要考慮提高8s配置文件中 BUFFERS 參數(shù)的值,以獲取較高的讀寫高速緩存比例。較低的讀寫高速緩存比例表明 8s 數(shù)據(jù)庫 正在進(jìn)行的磁盤讀寫操作比它應(yīng)該進(jìn)行的要多得多,這會大大降低數(shù)據(jù)庫引擎的整體性能。輸出的 seqscan 字段表明自數(shù)據(jù)庫啟動
25、或聯(lián)機(jī)以來執(zhí)行了多少次順序掃描。如果這個數(shù)字相當(dāng)大,比如說超過了 100000,并且還在不斷增加,那么這可能表明性能有問題,當(dāng)系統(tǒng)處于 OLTP 環(huán)境時更是如此。因而,您需要做進(jìn)一步的調(diào)查以搞清楚出現(xiàn)過多順序掃描的根源。在本文的后面我們將更詳細(xì)地討論這一問題。ovlock 字段表明 8s 數(shù)據(jù)庫 在使用了最大數(shù)量的鎖之后嘗試過再使用鎖的次數(shù)。如果該數(shù)字非零,那么您可能需要提高配置文件中 LOCKS 參數(shù)的值。ovbuf 字段表明 8s 數(shù)據(jù)庫 在使用了最大數(shù)量的緩沖區(qū)之后嘗試過再使用緩沖區(qū)的次數(shù)。如果該數(shù)字很大,比如說超過 100000,那么您需要提高 BUFFERS 參數(shù),以便用戶在需要從磁
26、盤訪問數(shù)據(jù)時不必等待緩沖區(qū)。這會縮短響應(yīng)時間,因而可以改善整體性能。我們還需要檢查與 LRU 有關(guān)的參數(shù),將它們的值調(diào)整到較低的 bufwait。另一組重要字段包括 ixda-RA、idx-RA、da-RA 及 RA-pgused。這些字段組合在一起表明 8s 數(shù)據(jù)庫 使用 8s 預(yù)讀機(jī)制的效率。預(yù)讀是這樣一種操作:它在順序掃描或索引讀期間提前將數(shù)據(jù)頁的數(shù)目從磁盤讀入內(nèi)存。理想情況是,預(yù)讀的頁數(shù)(即 ixda-RA、idx-RA 和 da-RA 之和)等于順序掃描或索引讀期間所使用的頁數(shù)(即 RA-pgused)。這表明預(yù)讀的頁百分之百地用于順序掃描和索引讀。如果二者之間存在顯著的差異,比如正
27、負(fù)差值達(dá)到 10000 以上,那么 8s 數(shù)據(jù)庫 目前就沒有很有效地使用預(yù)讀,而您可能需要調(diào)優(yōu)您的預(yù)讀參數(shù)(即 RA_PAGES 和 RA_THRESHOLD)以獲取更好的性能。消息日志消息日志也稱為聯(lián)機(jī)日志。它含有各種有關(guān)關(guān)鍵實例活動的信息,如檢查點(diǎn)的時間和持續(xù)時間、實例啟動和停止、備份和恢復(fù)狀態(tài)、邏輯日志備份狀態(tài)以及對主要配置參數(shù)的更改。消息日志還包含關(guān)鍵的錯誤(8s稱之為斷言失?。?,如磁盤 I/O 錯誤、鏡像錯誤、當(dāng)機(jī)塊、數(shù)據(jù)完整性錯誤以及共享內(nèi)存錯誤等等。在發(fā)生斷言失敗時,消息日志通常會將我們引向有關(guān)斷言失敗的("af.xxx")文件,該文件會記錄在數(shù)據(jù)庫引擎當(dāng)機(jī)時
28、有關(guān)實例活動的更詳細(xì)信息,還會就如何解決這一問題給我們提供一些建議。以下內(nèi)容摘自消息日志:00:57:53 00:57:53 Assert Failed: Unexpected virtual processor termination, pid =586, exit = 0x9 00:57:53 Who: Session(13709, omcadminnvlsys, 6538, 654709000)Thread(13740, sqlexec, 2704a558, 1)00:57:53 Results: Fatal Int
29、ernal Error requires system shutdown00:57:53 Action: Restart OnLine00:57:53 See Also: /var/tmp/af.35acfee100:57:53 Stack for thread: 13740 sqlexec上面的輸出告訴我們:某個 8s 虛擬處理器終止了,并毀壞了數(shù)據(jù)庫引擎。當(dāng)用戶"omcadmin"登錄到名為 nvlsys 的機(jī)器并執(zhí)行了一些數(shù)據(jù)庫操作(大部分是未正確執(zhí)行的 SQL 查詢),該機(jī)器上發(fā)生了這一錯誤。文
30、件 /var/tmp/af.35acfeel 記錄了出錯時有關(guān)數(shù)據(jù)庫引擎狀態(tài)的詳細(xì)統(tǒng)計信息。 狀態(tài)塊塊是物理存儲設(shè)備。它們應(yīng)該始終聯(lián)機(jī)。如果有任何塊當(dāng)機(jī)了,那么這表明數(shù)據(jù)遭到毀壞,需要立即引起注意。onstat -d 命令監(jiān)控當(dāng)前的塊狀態(tài)。檢查點(diǎn)檢查點(diǎn)是使磁盤上的頁與共享內(nèi)存緩沖池中的頁同步的過程。在檢查點(diǎn)期間,8s 數(shù)據(jù)庫 阻止用戶線程進(jìn)入臨界會話,并阻止所有的事務(wù)活動。因此,如果檢查點(diǎn)持續(xù)時間過長,那么用戶可能會經(jīng)歷系統(tǒng)掛起。在存在幾千個事務(wù)并且響應(yīng)時間至關(guān)重要的 OLTP 環(huán)境中,情況尤其如此。正如上面所解釋的那樣,可以通過查看消息日志來監(jiān)控檢查點(diǎn)持續(xù)時間,但更好更快的方法是使用 ons
31、tat -m命令。以下是該命令的樣本輸出:15:25:10 Checkpoint Completed: duration was 0 seconds.15:25:10 Checkpoint loguniq 231, logpos 0x1bb201815:35:30 Checkpoint Completed: duration was 19 seconds.15:35:30 Checkpoint loguniq 231, logpos 0x31b9018Fri Dec 20 11:48:02 200211:48:02 Checkpoint Completed: duration was 7 se
32、conds.11:48:02 Checkpoint loguniq 231, logpos 0x32e501814:27:37 Logical Log 231 Complete.14:27:40 Process exited with return code 142: /bin/sh /bin/sh -c /usr/gbasedbt/etc/log_full.sh 2 23 "Logical Log 231 Complete." "Logical Log 231Complete." 14:28:24 Checkpoint Completed: durat
33、ion was 22 seconds.14:28:24 Checkpoint loguniq 232, logpos 0x45801814:38:46 Checkpoint Completed: duration was 7 seconds.14:38:46 Checkpoint loguniq 232, logpos 0x10f5018如果檢查點(diǎn)持續(xù)時間始終超過 10 秒,那么您可能需要減少 LRU_MIN_DIRTY 和 LRU_MAX_DIRTY 配置參數(shù)的值以獲取更短的檢查點(diǎn)持續(xù)時間。同樣,如果 onstat -F 的輸出顯示極高的塊寫(比如高于 10000),并且這個數(shù)字還在不斷增加
34、,那么這可能表明出現(xiàn)了以下兩個問題中的一個:要么檢查點(diǎn)時間間隔太短,從而在檢查點(diǎn)之間清除程序沒有足夠的時間將所有經(jīng)過修改的緩沖區(qū)寫入磁盤,要么 AIO VP 太少,無法在檢查點(diǎn)期間共享繁重的磁盤寫。這樣,您需要重新檢查 CKPINTVL、LRUS、CLEANERS 和 NUMAIOVPS 配置參數(shù)的設(shè)置,并相應(yīng)地增加它們的值。我們可能還需要查看 onstat -F 的輸出來作為確定那些參數(shù)值的參考。dbspace 使用情況8s 數(shù)據(jù)庫管理員要不斷了解各個 dbspace 中的空間,這一點(diǎn)十分重要。如果某個 dbspace 缺少空間或把空間用完了,那么 8s 數(shù)據(jù)庫 會碰到麻煩。各種問題都可能出
35、現(xiàn):無法導(dǎo)入任何數(shù)據(jù)庫,無法創(chuàng)建任何表和索引,甚至無法對任何表和索引執(zhí)行插入和更新操作。這一點(diǎn)對于生產(chǎn)數(shù)據(jù)庫至關(guān)重要。我們需要監(jiān)控每個 dbspace 的增長,以便能夠?qū)@些問題采取更主動的方法。下面的腳本報告了各個 dbspace 的當(dāng)前空間使用情況,并計算其百分比。 select name dbspace , sum(chksize) allocated, sum(nfree) free,round(sum(chksize) - sum(nfree)/sum(chksize)*100) pcusedfrom sysdbspaces d, syschunks cwhere d.dbsnum
36、= c.dbsnumgroup by nameorder by name輸出如下所示:dbspace allocated free pcusedairgen_idx_dbs 1000000 763405 24airgen_main_dbs 1500000 295789 80llog 1000000 9947 99rootdbs 50000 36220 28temp1 250000 249947 0temp2 250000 249939 0上面的輸出有助于我們確定哪些 dbspace 已把空間用完了。要取得主動,請考慮在某個 dbspace 的磁盤使用情況接近 90% 時向該 dbspace 分
37、配額外的磁盤空間;本例中,我們需要特別注意 llog dbspace ,并且可能的話,就給它分配更多空間,以防止它把空間用完。dbspace I/ODbsapce I/O 是由磁盤讀和磁盤寫來衡量的。如果某些 dbspace 有繁重的磁盤讀寫操作,而另外一些 dbspace 幾乎不進(jìn)行任何讀寫操作,那么系統(tǒng)可能會出現(xiàn)一些磁盤 I/O 瓶頸。平衡得較好的Dbsapce I/O 將減輕系統(tǒng)磁盤 I/O 負(fù)載,從而會改善系統(tǒng)的整體性能。以下腳本將顯示各個 dbspace 的當(dāng)前 I/O 統(tǒng)計信息:select , fname15,25 path_name, sum(pagesread)
38、diskreads,sum(pageswritten) diskwritesfrom syschkio c, syschunks k, sysdbspaces dwhere d.dbsnum = k.dbsnumand k.chknum = c.chknumgroup by 1, 2order by 1輸出如下所示:name path_name diskreads diskwritesairgen_idx_dbs uild95/ltmp 3672 7964airgen_main_dbs uild95/ltmp 13545 32903llog uild95/ltmp 19 51633rootdb
39、s uild95/ltmp 211 43117temp1 uild95/ltmp 3015 3122temp2 uild95/ltmp 3218 3317我們的目標(biāo)是要使所有的 dbspace 都有平衡的磁盤讀寫操作。在大多數(shù)情況下,這是不現(xiàn)實的,但上面的輸出至少讓您對 dbspace I/O 的分配方式有了一個概念,可以幫助您標(biāo)識"最熱門的"dbspace - 那些磁盤讀寫最多的 dbspace 。如果有些 dbspace 的磁盤讀寫操作相當(dāng)繁忙而另外一些的讀寫操作則相當(dāng)空閑,那么您可能需要為 8s 數(shù)據(jù)庫 引擎調(diào)整甚至重新安排物理磁盤布局。我們可以使用 onstat -
40、D 和 onstat -g ioq 獲得類似的信息,前者顯示各個塊的磁盤讀和寫,而后者顯示磁盤 I/O 等待隊列信息。您可以通過查詢 sysmaster 數(shù)據(jù)庫中的 sysptprof 表來進(jìn)一步標(biāo)識哪些表具有最多的磁盤讀寫操作:select dbsname, tabname, (isreads + pagreads) diskreads, (iswrites + pagwrites) diskwritesfrom sysptproforder by 3 desc, 4 desc輸出類似于:dbsname tabname diskreads diskwritesairgen_10_0 fano
41、ut_param 84567 3094airgen_cm_db sysindices 78381 0airgen_10_0 ne_nmo_i 75819 5airgen_10_0 ne_nmo 75440 297airgen_cm_db sysprocbody 62610 28322airgen_10_0 systables 37342 466airgen_10_0 syscolumns 34539 4609airgen_10_0 457_484 32838 42airgen_10_0 453_480 30009 1airgen_10_5_old syscolumns 29531 4550ai
42、rgen_10_5 syscolumns 28824 4552airgen_10_0 456_483 25448 14airgen_10_0 458_485 23278 177airgen_10_5_old 452_483 根據(jù)從這個查詢獲得的輸出,您可能需要在 dbspace 間移動一些表以使磁盤 I/O 平衡得更好。共享內(nèi)存段太多的虛擬共享內(nèi)存段(通常多于三個)表明:最初的虛擬共享內(nèi)存段太小,數(shù)據(jù)庫引擎必須不斷分配額外的虛擬共享內(nèi)存段。這反過來影響了 8s 數(shù)據(jù)庫 性能,并且最終會損害系統(tǒng)的性能。onstat -g seg 命令顯示了 8s 數(shù)據(jù)庫引擎目前擁有多少共享內(nèi)存段:15:49:3
43、3 - 205824 KbytesSegment Summary:id key addr size ovhd class blkused blkfree 0 1381386241 a000000 177209344 220688 R 42984 280 1 1381386242 14900000 8388608 856 V 2048 0 2 1381386243 15100000 1048576 632 M 164 92 3 1381386244 15200000 8388608 856 V 2048 0 4 1381386245 15a00000 8388608 856 V 2008 40
44、5 1381386246 16200000 8388608 856 V 50 1998 Total: - - 211812352 - - 49302 2410 (* segment locked in memory)如果輸出顯示虛擬共享內(nèi)存段多于三個,那么您需要提高配置文件中 SHMVERSIZE 參數(shù)的值。其思想是,讓 8s 數(shù)據(jù)庫 在初始化時分配足夠的虛擬共享內(nèi)存,以便在用戶登錄到系統(tǒng)并執(zhí)行數(shù)據(jù)庫操作時無需分配更多的虛擬共享內(nèi)存。您可能還想使用 UNIX? ipcs 命令來查看 8s 共享內(nèi)存的大小。操作系統(tǒng)的整體性能由于 8s 數(shù)據(jù)庫引擎總是安裝在某個操作系統(tǒng)(主要是 UNIX)上,以準(zhǔn)
45、確地監(jiān)控或評估 8s 數(shù)據(jù)庫 性能,因此我們需要將操作系統(tǒng)的行為作為一個整體來考慮,在數(shù)據(jù)庫引擎駐留在非專用數(shù)據(jù)庫服務(wù)器上時尤其要這樣考慮。如果8s 數(shù)據(jù)庫 占用了太多 RAM(例如,如果系統(tǒng)有 512MB RAM,而 8s 數(shù)據(jù)庫 占用了 400MB 或更多作為其共享內(nèi)存),那么當(dāng)用戶執(zhí)行內(nèi)存密集型操作時,操作系統(tǒng)可能會經(jīng)歷頻繁的交換和掛起。當(dāng)內(nèi)存不足時,系統(tǒng)必須將一些數(shù)據(jù)頁從內(nèi)存交換到磁盤,以便為新數(shù)據(jù)騰出更多空間。如果系統(tǒng)內(nèi)存不足,那么 CPU 可能也會遭殃。有不少 UNIX 實用程序可以監(jiān)控操作系統(tǒng) CPU 和內(nèi)存的整體利用率。以下是來自"top"實用程序的輸出:l
46、oad averages: 1.12, 1.02, 1.07 10:17:30123 processes: 120 sleeping, 1 zombie, 2 on cpuCPU states: 70.5% idle, 26.5% user, 2.8% kernel, 0.3% iowait, 0.0% swapMemory: 3072M real, 76M free, 588M swap in use, 440M swap freePID USERNAME THR PRI NICE SIZE RES STATE TIME CPU COMMAND28349 omcadmin 4 0 0 86M
47、 55M cpu10 970:25 6.85% CS_App.prt17782 gbasedbt 5 30 -10 1631M 1594M sleep 50.0H 4.66% oninit.exe17784 gbasedbt 5 59 -10 1631M 1594M sleep 102.9H 4.12% oninit.exe17786 gbasedbt 5 59 -10 1631M 1591M sleep 25.5H 2.53% oninit.exe571 root 1 58 0 361M 129M sleep 19.0H 1.36% em_mis17785 gbasedbt 5 59 -10
48、 1631M 1592M sleep 57.8H 1.05% oninit.exe5470 omcadmin 1 0 0 1960K 1408K cpu15 0:00 0.26% top上面的輸出包含兩部分。第一部分為您匯總了操作系統(tǒng)的 CPU 和內(nèi)存的整體使用情況,第二部分則提供了有關(guān)每個處理器的詳細(xì)信息。其它實用程序(如 vmstat、iostat、ps -ef 和 sar)在收集操作系統(tǒng)當(dāng)前的性能統(tǒng)計信息方面也很有用。vmstat 顯示目前操作系統(tǒng)交換了多少內(nèi)存;iostat 和 sar 顯示了當(dāng)前在所有物理磁盤中磁盤 I/O 的分配;而 ps -ef 打印出當(dāng)前各個處理器的登錄時間、C
49、PU 及內(nèi)存使用情況的詳細(xì)信息。此外也有許多圖形工具可用,這些工具使您能夠繪制操作系統(tǒng)資源利用率和性能的動態(tài)變化。監(jiān)控數(shù)據(jù)庫活動對數(shù)據(jù)庫活動進(jìn)行監(jiān)控的目的在于確保每個數(shù)據(jù)庫時刻都將其能力發(fā)揮到了極致。這意味著:您必須留意潛在的性能問題,確定其根源并將其消滅在萌芽狀態(tài)。以下是要留意的幾個方面。表擴(kuò)展塊擴(kuò)展塊是一塊物理上連續(xù)的頁。然而,如果一個表有多個擴(kuò)展塊,那就不能保證這些擴(kuò)展塊是連續(xù)的;擴(kuò)展塊可能會散布在表所駐留的整個 dbspace 上。物理頁的連續(xù)性對于性能十分重要。當(dāng)數(shù)據(jù)頁連續(xù)時,訪問磁盤數(shù)據(jù)所用的時間就最短,而數(shù)據(jù)庫也能連續(xù)地讀取行。如果表有太多擴(kuò)展塊,那么那些擴(kuò)展塊極有可能相互交錯。
50、這極大地影響了性能,因為當(dāng)您檢索某個表的數(shù)據(jù)時,磁頭需要對屬于該表的多個非連續(xù)擴(kuò)展塊進(jìn)行尋道,而不是對具有連續(xù)物理頁的一個大擴(kuò)展塊進(jìn)行尋道。這會顯著地降低磁盤尋道速度。下面的腳本檢測具有多個擴(kuò)展塊的數(shù)據(jù)庫表:select t.tabname, count(*) num_extfrom sysmaster:sysextents e, airgen:systables twhere e.tabname=t.tabnameand dbsname = "airgen"and t.tabname not like "sys%"group by 1having co
51、unt(*) > 1order by 2 desc輸出如下所示:tabname num_extnmoattrclassmap 14attrclass 11networkmoclass 3fanout_param 3fanout_comp 2ne_nmo 2nenmoclassmap 2join_map 2如果除了大型分段表以外,任何表的擴(kuò)展塊超過了 10 個,那么您應(yīng)該考慮重新構(gòu)建這些表以合并擴(kuò)展塊。對于較大的數(shù)據(jù)庫或者大小設(shè)置不是很好的數(shù)據(jù)庫,我們可能還會關(guān)注擴(kuò)展塊的最大數(shù)目,或者會擔(dān)心針對索引的 32GB 限制。索引層索引的層數(shù)也可能會對性能產(chǎn)生不利影響。索引層越多,8s 數(shù)據(jù)庫 到
52、達(dá)索引葉節(jié)點(diǎn)所需的探測也就越多。而且,如果葉節(jié)點(diǎn)被拆分或合并,那么整個索引對這一變化進(jìn)行調(diào)整將要花費(fèi)更多的時間。例如,如果索引只有兩層,那么只需要調(diào)整兩層,但如果索引有四層,那么相應(yīng)地就需要對所有四層進(jìn)行調(diào)整。用于這一調(diào)整的時間當(dāng)然也就長得多。在 OLTP 環(huán)境中會進(jìn)行頻繁的插入、刪除和更新,這些操作會導(dǎo)致不斷地對索引進(jìn)行拆分和合并,因此上述問題也就格外明顯。下面的腳本標(biāo)識每個索引的層數(shù):select idxname, levels from sysindexesorder by 2 desc輸出如下所示:idxname levelsobjdesc 3fanout_param_i 3458_4
53、85 3457_484 3idxname 2tabgtor 2tabgtee 2如果哪個索引超過了 4 層,您可能就需要考慮刪除和重新構(gòu)建該索引,從而合并其層,以獲取更好的性能。索引唯一性索引的重復(fù)程度很高會嚴(yán)重地影響更新和刪除的性能。假定表 customer 的 customer_type 列上有一個索引,而可能的 customer_type 代碼只有五種。如果這個表有一百萬行,那么可能有 200000 行具有相同的 customer_type 代碼。B-樹存儲鍵值,其后跟一個指向每個物理行的指針列表。在必須刪除或更新任何鍵值時,問題出現(xiàn)了。8s 數(shù)據(jù)庫 必須找遍所有的重復(fù)內(nèi)容,直到找到要刪
54、除或更新的正確鍵為止!下面的腳本用來標(biāo)識重復(fù)程度很高的索引:select tabname, idxname, nrows, nuniquefrom systables t, sysindexes Iwhere t.tabid =i.tabidand t.tabid > 99and nrows > 0and nunique > 0 輸出如下所示:tabname idxname nrows nuniquebsc_dte bscdte_i 6 6omcgttready 231_413 1 1systemrelease 451_478 3 3neclass 452_479 31 12
55、sysrelneclassmap 453_480 33 3proxynemgrmap 454_481 1 1networkmoclass 455_482 362 199nenmoclassmap 456_483 492 12attrclass 457_484 1191 924nmoattrclassmap 458_485 2901 199fanout_comp fanout_comp_i 915 199fanout_comp fanout_comp_i2 915 199fanout_comp fanout_comp_i3 915 82fanout_param fanout_param_i 28
56、94 196在理想情況下,nunique 列中所出現(xiàn)的全部值都應(yīng)該與 nrow 列中的全部值相等,即索引中的每個鍵都是唯一的。根據(jù)行數(shù)(上面的 nrow 列)和唯一鍵數(shù)(上面的 nunique 列),我們可以計算每個索引唯一性的百分率: (nunique/nrows)*100百分率越高,索引的唯一性就越高。為了避免因索引重復(fù)程度很高而引起的性能瓶頸,您可以使用復(fù)合索引來替換原來的索引,復(fù)合索引結(jié)合了重復(fù)程度很高的列與唯一性比較高的列。利用上面的示例,您可以將主鍵列 customer_id 添加到原來的索引,將它變成一個復(fù)合列(例如," create index index_name
57、on customer (customer_type, customer_id)")。順序掃描對表進(jìn)行順序存取有時會降低性能,因為數(shù)據(jù)庫引擎必須掃描整個表以選取滿足查詢條件的行。如果表很小,比如說幾百行,那么順序存取不會對性能造成什么影響;因為當(dāng)數(shù)據(jù)庫引擎第一次掃描它時,該表會駐留于內(nèi)存中,而當(dāng)數(shù)據(jù)庫引擎下一次掃描它時,可以直接從內(nèi)存檢索該表中的所有數(shù)據(jù)。這實際上是使用順序掃描的有效方式。但如果表很大,比如說超過了 100000 行,那么重復(fù)的順序掃描會對性能造成致命的影響。下面的腳本將標(biāo)識具有多重順序掃描的表:select dbsname, tabname, sum(seqscan
58、s) tot_scansfrom sysptprofwhere seqscans > 0and dbsname not like "sys%"group by 1,2order by 3 desc輸出如下所示:dbsname tabname tot_scans airgen_10_0 systemrelease 2352airgen_10_5_old systemrelease 1596airgen_10_5 systemrelease 1596airgen_10_0 fanout_comp 1587airgen_10_5_old sysusers 1248airge
59、n_10_0 sysusers 1241airgen_10_5 sysusers 1231airgen_10_0 join_map 1036airgen_10_0 fanout_param 958airgen_10_0 func_call 770airgen_10_5 nenmoclassmap 586airgen_10_5_old nenmoclassmap 586從上面的輸出可以看出 airgen_10_0 表的順序掃描數(shù)很高。如果它是一個具有幾千甚至幾百萬行的大表,那么您可能需要考慮向該表添加一些索引,或者考慮使用程序偽指令來強(qiáng)制內(nèi)部查詢優(yōu)化器為訪問該表中的數(shù)據(jù)選擇索引而不是順序掃描。 監(jiān)控會話活動有關(guān)會話活動的統(tǒng)計信息在確定潛在的性能問題及故障診斷方面很有用。使用本文前面討論的監(jiān)控工具,我們可以收集哪些會話活動統(tǒng)計信息呢?常規(guī)會話統(tǒng)計信息sysmaster 數(shù)據(jù)庫中的 syssessions 表存儲各個會話的常規(guī)信息,如登錄名、登錄時間、會話所登錄的主機(jī)機(jī)器、操作系統(tǒng)的進(jìn)程標(biāo)識和當(dāng)前狀態(tài)等等
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 山東省F市新就業(yè)形態(tài)勞動者勞動權(quán)益保障問題研究
- 銑床加工流程
- 心理健康5A示范校匯報
- 慢阻肺健康宣教指南
- 頤和園教學(xué)說課課件
- 腸道健康的重要性
- 頸椎術(shù)后護(hù)理課件
- 教師培訓(xùn)心得體會交流
- 中醫(yī)內(nèi)科學(xué):瘧疾診治要點(diǎn)
- 設(shè)備檢修培訓(xùn)內(nèi)容
- FZ/T 01118-2012紡織品防污性能的檢測和評價易去污性
- 飛行機(jī)器實驗室 PX4FLOW智能光流傳感器使用說明 V1.3
- 2020年廣州市初三英語中考模擬考試+答案
- 高速公路機(jī)電系統(tǒng)培訓(xùn)課件
- 2023年心肺復(fù)蘇(CPR)指南解讀
- 電廠新員工安規(guī)考試
- 山東省濟(jì)南市各縣區(qū)鄉(xiāng)鎮(zhèn)行政村村莊村名居民村民委員會明細(xì)
- 西方管理學(xué)名著提要
- 混凝土構(gòu)件之梁配筋計算表格(自動版)
- 閥門設(shè)計計算書(帶公式)
- 新蘇科版七年級下冊初中數(shù)學(xué)全冊教案
評論
0/150
提交評論