李學(xué)國 沈應(yīng)蘭
(重慶科創(chuàng)職業(yè)學(xué)院,重慶 402160)
Oracle數(shù)據(jù)庫系統(tǒng)是美國ORACLE公司(甲骨文)提供的以分布式數(shù)據(jù)庫為核心的一組軟件產(chǎn)品,是目前最流行的C/S或B/S體系結(jié)構(gòu)的數(shù)據(jù)庫之一。Oracle數(shù)據(jù)庫是目前世界上使用最為廣泛的數(shù)據(jù)庫管理系統(tǒng),作為一個通用的數(shù)據(jù)庫系統(tǒng),它具有完整的數(shù)據(jù)管理功能。組成Oracle數(shù)據(jù)庫的物理結(jié)構(gòu)用來存儲、管理、保護以及讀取數(shù)據(jù),在創(chuàng)建數(shù)據(jù)庫時,對數(shù)據(jù)文件初始布局以及表空間的管理類型對性能都有較大的影響。實際項目中使用的Oracle數(shù)據(jù)庫經(jīng)過一段時間的運行,在線保存的數(shù)據(jù)量和業(yè)務(wù)處理的數(shù)據(jù)量在逐漸增大,最初的Oracle設(shè)置,與現(xiàn)在實際需要的運行性能有一定差距,需要進行一些優(yōu)化調(diào)整。
合理地配置并創(chuàng)建數(shù)據(jù)庫有助于保證數(shù)據(jù)庫的優(yōu)良性能,并且數(shù)據(jù)庫大小會隨著使用時間成倍增長,因此創(chuàng)建最優(yōu)性能的數(shù)據(jù)庫一般具有以下幾個原則:
1.強制數(shù)據(jù)庫中創(chuàng)建的每一個表空間都必須是本地管理的。本地管理表空間能比已經(jīng)被棄用的字典管理技術(shù)提供更好的性能。
2.確保數(shù)據(jù)庫為每個用戶自動分配一個默認(rèn)的永久表空間。這可以保證在創(chuàng)建用戶時,自動分配一個默認(rèn)的表空間,而不是SYSTEM系統(tǒng)表空間。你不能讓用戶總是將對象建在SYSTEM表空間中,因為這樣會對性能和可用性產(chǎn)生負(fù)面影響。
3.確保數(shù)據(jù)庫會為每個用戶自動分配一個默認(rèn)的臨時表空間。這可以保證在創(chuàng)建用戶時,自動分配一個臨時表空間,而不是SYSTEM表空間。你不能總是讓用戶使用SYSTEM表空間作為排序操作運算的臨時表空間,因為這樣會對性能和可用性產(chǎn)生負(fù)面影響。
如創(chuàng)建以下數(shù)據(jù)庫:
創(chuàng)建數(shù)據(jù)庫時,還需要考慮影響可維護性的功能。容易維護的數(shù)據(jù)庫能正常運行更長時間,而這也正是總體性能的一個重要部分?!敖鉀Q方案”部分的CREATE DATABASE語句同時還考慮了下面這些可維護性方面的特性。(1)創(chuàng)建一個自動的UNDO表空間。這使Oracle可以自動管理回滾段,你也就不必定期進行監(jiān)控和微調(diào)了。(2)按照環(huán)境中的一定標(biāo)準(zhǔn),將數(shù)據(jù)文件放到相應(yīng)文件夾中。這有助于維護和管理,從而使數(shù)據(jù)庫具備更好的長期可用性,從而獲得更好的性能。
在對數(shù)據(jù)庫進行操作時,如果需要在移除數(shù)據(jù)以后還能選擇進行數(shù)據(jù)回滾(而不是立即提交),那么就應(yīng)該使用Delete語句。但是,Delete語句的缺點是它會產(chǎn)生大量的撤銷(undo)和重做信息。因此,對于大表來說,Truncate語句通常是移除數(shù)據(jù)最有效的方法。
Truncate語句的另一個特性就是它會將表的高水位線重新歸零。當(dāng)你使用Delete語句移除表中數(shù)據(jù)時,高水位線將不會發(fā)生變化。使用Truncate語句并重置高水位線的一個優(yōu)點就是,全表掃描查詢僅搜索位于高水位線之下的存儲塊中的數(shù)據(jù)行。這對于進行全表掃描的查詢性能具有很大的影響。
如:使用Truncate語句移除COMPUTER_SYSTEMS表中的所有數(shù)據(jù)
Truncate語句的另一個副作用就是,如果一張表定義了主鍵,并且這個主鍵是其子表的外鍵,那么不能截斷該表,即使這個子表包含零個數(shù)據(jù)行也是如此。在這種場景下,試圖截斷父表時,Oracle將會拋出下面這個錯誤:
Oracle之所以會阻止你截斷父表,是因為在一個多用戶系統(tǒng)中,有可能在截斷子表與接下來截斷父表之間的這段時間里,另一個會話向子表中填充數(shù)據(jù)行。在這種情況下,必須暫時禁用子表所引用的外鍵約束,執(zhí)行Truncate語句,然后再重新啟用約束。
比較Truncate語句和Delete語句的功能。Oracle的確允許使用Delete語句從父表中移除數(shù)據(jù)行,而不管是否有指向子表的約束存在(假設(shè)子表中的數(shù)據(jù)為零行)。這是因為Delete會生成重做,具有讀一致性,并且能夠回滾。表1-1總結(jié)了Delete和TruncateE之間的區(qū)別。
表1 -1 Delete和Truncate比較
如果需要使用Delete語句,就必須使用COMMIT或ROLLBACK來結(jié)束事務(wù)。提交一條Delete語句就使得數(shù)據(jù)永久消失:
如果提交一條ROLLBACK語句而不是COMMIT,那么表中的數(shù)據(jù)將會與執(zhí)行Delete語句之前一樣。
使用DML語句時,可以查詢V$TRANSACTION視圖來確認(rèn)事務(wù)的細(xì)節(jié)。例如,假設(shè)你往表中插入了數(shù)據(jù),在進行COMMIT或ROLLBACK之前,能夠看到當(dāng)前所連接會話的活動事務(wù)信息如下所示:
當(dāng)有一張表,其中的數(shù)據(jù)行可能會存儲在多個數(shù)據(jù)塊中。這種情況會增加I/O使用率,并導(dǎo)致對這張表的查詢運行速度變慢。因此需要重建跨多個數(shù)據(jù)塊的數(shù)據(jù)行,使每一行數(shù)據(jù)位于一個數(shù)據(jù)塊中,從而提高表的性能。但是從表中取出數(shù)據(jù)時,可能會受到行鏈接的影響,因此必須刪除表中的行鏈接。
解決行鏈接問題的一個辦法就是使用MOVE語句。移動一張表時,Oracle需要表上的排它鎖。因此當(dāng)要進行移動操作的表沒有活動事務(wù)時,應(yīng)該執(zhí)行MOVE操作。同時,作為移動操作的一部分,所有數(shù)據(jù)行都會被分配一個新的行編號(ROWID)。這會使表的所有索引失效。因此作為移動操作的一部分,你需要重建所有與進行移動的表相關(guān)的索引。如移動EMP表:
在數(shù)據(jù)塊中保留有一定量的空間,以便容納數(shù)據(jù)行的增長。通常數(shù)據(jù)行大小增加是由于執(zhí)行了增加列長度值的UPDATE語句。如果塊中沒有足夠的空間來容納所增長的數(shù)據(jù),那么Oracle就會創(chuàng)建一個指針,指向具有足夠空間的數(shù)據(jù)塊,并在該數(shù)據(jù)塊中存儲一部分行數(shù)據(jù)。當(dāng)一個數(shù)據(jù)行存儲在兩個或多個數(shù)據(jù)塊中時,就稱為行鏈接。這可能會導(dǎo)致潛在的性能問題,因為Oracle將不得不從多個數(shù)據(jù)塊(而不是一個)中取鏈接的一行數(shù)據(jù)。
少量的行鏈接不會對性能有很大的影響。一個大致的準(zhǔn)則是,如果表中超過15%的數(shù)據(jù)行是鏈接的,那么你就要執(zhí)行正確的操作了(例如移動表以重新進行組織)。
數(shù)據(jù)塊中所保留的空閑存儲空間大小由表的存儲參數(shù)PCTFREE決定。PCTFREE的默認(rèn)值為10,也就是數(shù)據(jù)塊保留10%的空間,以備更新操作使用。如果某張表中的列初始插入空值(null),更新之后包含較大的值,那么就要考慮將PCTFREE設(shè)置為更高的值,例如40%。這將有助于阻止行鏈接的產(chǎn)生。
相反,如果你有一張表,在插入數(shù)據(jù)行之后就再也不會更新,那么可以考慮將PCTFREE值設(shè)置為0。這可以使每個數(shù)據(jù)塊中容納更多的行,從而減少取出數(shù)據(jù)時需要讀取的磁盤空間數(shù)量(也就提高了性能)。
[1]陳雍.基于ORACLE數(shù)據(jù)庫應(yīng)用系統(tǒng)性能調(diào)整和優(yōu)化研究[學(xué)位論文],江西師范大學(xué),2008
[2]Vaidyanatha.G.K等.Oracle性能優(yōu)化技術(shù)內(nèi)幕.北京:機械工業(yè)出版社,2002.5
[3]薩師萱,王珊.數(shù)據(jù)庫系統(tǒng)概論.北京:高等教學(xué)育出版社,2006