正常情況下往表中新建記錄時,數(shù)據(jù)庫系統(tǒng)會將數(shù)據(jù)寫入到塊并會像這行記錄提供一個ROWID值。這個值記錄了這條記錄在硬盤上存儲的位置。在更新某 條記錄的時候,也是如此。數(shù)據(jù)庫系統(tǒng)會根據(jù)ROWID的值將需要更新的記錄從硬盤中讀取到塊中;然后更新完畢后,再將塊中的記錄保存到硬盤對應的位置。更 新過程中,ROWID列的值通常情況下不會改變。
但是如果一個塊的容量不能夠容納一條記錄。也就是會所,當單個數(shù)據(jù)塊沒有足夠的空間來保存新建的一行記錄或者更新的某行記錄時,就會發(fā)生鏈化現(xiàn)象。 到一個數(shù)據(jù)庫的容量不足以容納一條記錄時,那么數(shù)據(jù)庫就不得不動用更多的數(shù)據(jù)塊來保存這條記錄。在Oracle數(shù)據(jù)庫中,如果某條記錄需要利用多個數(shù)據(jù)庫 來保存,我們往往把這行記錄叫做鏈化行。而在訪問一行記錄時,如果需要訪問多個數(shù)據(jù)塊,則會比訪問單個數(shù)據(jù)塊需要耗費更多的服務器資源,會大大降低數(shù)據(jù)庫 性能。我們把這種因為鏈化行而導致的數(shù)據(jù)庫性能下降的現(xiàn)象叫做鏈化現(xiàn)象。根據(jù)專家統(tǒng)計,嚴重的話,鏈化現(xiàn)象可能降低數(shù)據(jù)庫10%的性能,甚至更多。所以數(shù) 據(jù)庫管理員如果在數(shù)據(jù)庫部署中,能夠有效避免鏈化現(xiàn)象,那么就可以在很大程度上提升數(shù)據(jù)庫的性能
一、 如何判斷是否有鏈化現(xiàn)象的存在?
那么數(shù)據(jù)庫管理員該如何判斷數(shù)據(jù)庫中是否有鏈化現(xiàn)象的存在呢?如果沒有工具,光憑數(shù)據(jù)庫管理員的眼力或者經(jīng)驗的話,是很難判斷的。數(shù)據(jù)庫管理員必須 找一個順手的工具。其實Oracle數(shù)據(jù)庫設計這已經(jīng)預計到這個問題對于數(shù)據(jù)庫性能的不利影響。為此在數(shù)據(jù)庫中已經(jīng)提供了追蹤、分析鏈化現(xiàn)象的工具。在 Oracle數(shù)據(jù)庫安裝主目錄的/rdbms/admin下有一個腳本文件,名字叫做utlchain.sql。這是Oracle數(shù)據(jù)庫自帶的一個腳本文 件。我們可以利用文本編輯器等工具來打開這個腳本文件,可以看到這個腳本文件主要是用來創(chuàng)建一個表,用來保存分析腳本現(xiàn)象所需要的內(nèi)容。
第一步:創(chuàng)建所需要的表。
首先,數(shù)據(jù)庫管理元需要執(zhí)行Oracle數(shù)據(jù)庫提供的utlchain.sql腳本文件。這個文件位于Oracle主目錄下的/rdbms /admin下。這個腳本主要的用途就是建立一個表格。這個表格很有用。數(shù)據(jù)庫系統(tǒng)會把分析的結(jié)果保存到這個表中。默認情況下,這個表格在安裝數(shù)據(jù)庫時并 不會自動生成。如果數(shù)據(jù)庫管理員需要分析數(shù)據(jù)庫中是否存在鏈化現(xiàn)象,那么就需要手工執(zhí)行這個腳本文件,以建立這張表格。這張表格中,主要有表名、 HEAD_ROWID列等等。
第二步:分析目的表格。
創(chuàng)建上面的表格后,默認情況下里面是沒有數(shù)據(jù)的。因為還沒有進行相關(guān)的分析。假設現(xiàn)在在數(shù)據(jù)庫中有一個Product的表格,主要用來保存產(chǎn)品信 息?,F(xiàn)在數(shù)據(jù)庫管理員想要知道,數(shù)據(jù)庫系統(tǒng)在操作這張表格數(shù)據(jù)的時候,是否存在有鏈化現(xiàn)象。此時,數(shù)據(jù)庫管理員就需要利用下面的語句來進行分析查詢。
Analyze table product list chained rows;
上面這條語句的作用,就是會分析product這張表格。判斷這張表格中的記錄是否存在在不同的塊中。如果這個product表格中,有記錄存儲在 不同的塊中,則這條語句就會把相關(guān)的結(jié)果保存到剛才建立的表中。所以,如果數(shù)據(jù)庫管理員查詢剛才建立的表chained_rows,如果這個表中有相關(guān)記 錄的話,則就說明數(shù)據(jù)庫中存在鏈化現(xiàn)象。數(shù)據(jù)庫管理員需要采取相應的措施來避免這種情況。如果沒有的話最好。
不過在使用這個語句的時候,需要注意幾點。一是每次分析完治后,最好把這個表個中的記錄刪除。因為下次分析的時候,如果表中有記錄的話,系統(tǒng)不會自 動刪除。所以在分析另外一個表的時候,如果也有鏈化現(xiàn)象。那么此時相關(guān)的記錄就會很多,數(shù)據(jù)庫管理員閱讀的時候會出現(xiàn)故障。二是這個分析的頻率最好頻繁一 點。當數(shù)據(jù)庫中的記錄比較多時或者數(shù)據(jù)更新比較頻繁的情況下,最好能夠每隔幾天就執(zhí)行一下這個分析語句,以判斷是否有鏈化現(xiàn)象的存在。等到大量記錄或者表 格有鏈化現(xiàn)象的時候,處理起來就會比較困難了。所以對于大部分事務型的數(shù)據(jù)庫系統(tǒng),數(shù)據(jù)庫管理員要養(yǎng)成一個周期性分析的習慣。對于大部分的數(shù)據(jù)庫優(yōu)化作業(yè) 來說,事先追蹤遠遠比時候解決要重要的多。當問題出現(xiàn)后再去解決的話,往往會大費周章,有些即使采取有效的措施,也指能夠避免后續(xù)的操作不會出現(xiàn)這種情 況。要解決以前的記錄問題,只有重新導出、導入數(shù)據(jù)后才能夠徹底解決。顯然這會增加工作量與數(shù)據(jù)風險。為此筆者再不厭其煩的強調(diào)一次,對于這個鏈化現(xiàn)象的 追蹤分析,最好能夠每個星期執(zhí)行一次。特殊情況下,還可以利用任務計劃,每天執(zhí)行一次。盡早發(fā)現(xiàn)問題,并采取有效措施來避免這種情況。
二、 如何避免鏈化現(xiàn)象?
當數(shù)據(jù)庫發(fā)現(xiàn)有鏈化現(xiàn)象時,就需要及時調(diào)整相關(guān)設置,來避免這種情況。造成鏈化現(xiàn)象的主要原因是由于塊的大小設置不合適所造成的。如果一個數(shù)據(jù)塊的 大小不能夠容納一條記錄,那么就容易造成鏈化現(xiàn)象。所以如果適當調(diào)整數(shù)據(jù)塊的大小,能夠在很大程度上避免這個鏈化現(xiàn)象。在Oracle數(shù)據(jù)庫中,為了有效 避免鏈化現(xiàn)象,可以通過調(diào)整參數(shù)PCTFREE來實現(xiàn)。這個參數(shù)的主要用途就是為更新一個塊所保留的空間。有時候系統(tǒng)默認的值往往不能夠滿足需求。為此需 要數(shù)據(jù)庫管理員根據(jù)實際需要設置合適的值。值得注意的是,這個值可以根據(jù)表來進行設置。為此如果數(shù)據(jù)庫管理員認為某張表的記錄可能比較長,需要占用比較大 的空間時,則可以針對這張表設置比較大的塊。
雖然通過調(diào)整PCTFREE參數(shù)可以有效避免鏈化現(xiàn)象。但是有時候表設計不當也是造成這個問題的主要原因之一。如有一張表M_PRODUCT表格, 用來存放產(chǎn)品信息。在這張表中,其產(chǎn)品信息主要分為成品與原材料兩類。其中原材料這類產(chǎn)品中,在系統(tǒng)中需要記錄詳細的產(chǎn)品規(guī)格信息,而且還需要同時記錄中 英文內(nèi)容。所以光這個產(chǎn)品規(guī)格,中英文加起來最多的就有3000個左右的字符。而成品信息的話相對來說比較簡單。此時這個表中的記錄就存在著兩極分化的現(xiàn) 象。有些記錄的容量很大,需要利用多個數(shù)據(jù)塊來進行保存,就發(fā)生了鏈化現(xiàn)象。而有些記錄的話,容量不是很大。此時雖然可以通過給這個表設置比較大的數(shù)據(jù)塊 來解決這個鏈化現(xiàn)象;但是同時也會浪費數(shù)據(jù)空間。因為還有大部分記錄的話,根本用不到這么大的塊空間。所以在這種情況下,片面調(diào)整PCTFREE參數(shù),會 降低硬盤空間的利用率。此時,筆者認為最好能夠調(diào)整數(shù)據(jù)庫表格的設計。如可以將產(chǎn)品規(guī)格字段保存在另外一個表格中,然后通過關(guān)鍵字連接到Product表 格中。如此的話,在Product表格中,所有記錄的的長度都會差不多。此時再根據(jù)需要來調(diào)整PCTFREE參數(shù),不僅可以有效避免鏈化現(xiàn)象,而且還同時 提高了硬盤空間的利用率。當然,對于新建立的表格,需要適當?shù)奶岣逷CTFREE參數(shù),避免其出現(xiàn)鏈化現(xiàn)象。不過這個基表的調(diào)整,對于已經(jīng)投入使用的數(shù)據(jù) 庫系統(tǒng)來說,調(diào)整的動作有點大,會影響用戶的正常使用。為此在數(shù)據(jù)庫設計的時候,就需要跟用戶充分的溝通。在數(shù)據(jù)庫初始化設計時,就能夠預見到這種情況。 所以筆者一直強調(diào),數(shù)據(jù)庫優(yōu)化一定要做在前。
另外,如果數(shù)據(jù)庫中的記錄很少更新,如一些決策分析系統(tǒng)或者數(shù)據(jù)倉庫,其只有在剛開始的時候需要大量的導入數(shù)據(jù)。導入數(shù)據(jù)后對數(shù)據(jù)庫中的內(nèi)容基本上 不會再更新。此時不需要把PCTFREE參數(shù)設置的太大。可以設置比較小的值,能夠提高硬盤空間的利用率,讓表空間存儲更多的記錄??梢?,PCTFREE 參數(shù)的大小沒有一個固定的參考標準。其主要根據(jù)數(shù)據(jù)庫的用途、表中記錄的更新程度、記錄的大小等等決定的。如何確定一個合理的PCTFREE參數(shù)值,以減 少鏈化現(xiàn)象同時提高表空間的利用率,這也正是數(shù)據(jù)庫優(yōu)化的難點與挑戰(zhàn)所在。
更多信息請查看IT技術(shù)專欄