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