在Oracle數據庫中,Insert、Update、Delete三個操作是對數據庫中的數據進行插入、更新以及刪除。在進行這些操作時,如果數據庫中的記錄比較多時,則所需要的時間比較長。如需要利用一個Update語句更新大量記錄時,即使更新的內容很簡單,如只是將價格提升10%,但是仍然需要花費比較成的時間。所以從某種程度上來說,進行這些操作時其執行速度跟內容的大小關系不大,反而跟記錄的多少卻有很大的關系。那麼在Oracle數據庫中,能否采取一些措施來提高這些操作的速度呢?為此筆者有如下兩個建議,希望對大家有所幫助。
建議一:在執行這些操作時不向重做日志中寫東西。
在執行更新、插入、刪除操作時,默認情況下,其在更新數據的同時,也會像重做日志文件中記錄這些改變。如利用Update語句將數據庫中產品的價格提高10%時。數據庫會更改這些價格,同時也會在重做日志中記錄這些改變。顯然,更新一個數據,數據庫要進行兩項工作。為此,當更新所涉及到的記錄比較多時,這個更新操作就可能要耗費比較長的時間。此時,可能需要更新內容本身字符的多少,跟其更新的效率並不具有很大的聯系。其執行的速度主要跟其更新所涉及到的記錄數量有關。
為此,有時候在追求其更快的執行速度時,我們往往需要在這些語句中加入一個nologging選項。如在使用Update語句更新價格信息時,加上這個Nologging選項就可以顯著提高其執行的速度。更新操作所涉及到的記錄越多,其效果越明顯。那麼這個可選項到底有什麼作用呢?顧名思義,這個參數就是告訴數據庫系統,在執行這個操作的時候,不要忘重做日志中記錄相關的信息。也就是說,此時數據庫系統只需要做一件工作即可,至需要更改數據,而不會產生重做日志文件。在理想的狀態下,這麼設置可以將這些操作的速度提高一倍。所以在進行大規模的更新、刪除、插入記錄等操作時,筆者往往建議大家加上這個可選項,以提高執行的速度。
不過如果采用這個可選項的話,也有一個缺點。因為其不會產生重做日志,所以如果數據更新失敗或者出現其他一些意外故障,就不能夠利用重做日志來恢復數據。為此如果對於數據的准確性要求非常苛刻的話,采用這種方式來提高這些操作的執行速度,可能並不是一種合理的方法。其是以犧牲數據的安全性來獲取性能上的改進。雖然這些操作出現故障的幾率比較少見,但是在使用這個可選項時,數據庫管理員必須要了解這個風險。在可能的情況下,即使做好風險的評估與預防。
建議二:調整重做日志的大小來提高執行速度。
上面這種方法由於不產生重做日志,雖然提高了執行的速度,但是也帶來了一定的安全風險。那麼是否有兩全其美的方法呢,即能夠提高執行速度,又能夠保障數據的安全呢?在Oracle數據庫中就有這麼一個兩全其美的方法。就是調整重做日志的大小來提高執行速度。來具體講解這個方案時,筆者要強調的是此時數據庫仍然會產生重做日志。為此其效果沒有上面這種方法好。但是其可以保障數據的安全,在出現問題時,仍然可以利用重做日志來恢復數據。所以說,這是在安全與速度之間實現了一個均衡。
在對記錄進行大批量的更新時,在重做日志中產生相關的記錄會花費比較多的時間。其實這個時間也可以分為兩個部分。一是往重做日志中記錄相關信息的時間;二是重做日志進行切換的時間。在Oracle數據庫的聯機重做日志中,往往同時有多個重做日志文件。當某個重做日志文件滿時,則會將後續的記錄寫到下一個重做日志文件中。但是在寫入之前,其需要對這個即將被覆蓋的重做日至進行歸檔,也就是進行備份。在這個備份的時候,Update等更新操作不得不進行等待。要等待其歸檔完成之後,再繼續進行更新並產生重做記錄。也就是說,聯機重做日志只有在被歸檔後才能夠被覆蓋,在這個歸檔的過程中,其他相關的操作必須等待,直到有可能的聯接重做日志。為此,如果這個重做日志的文件比較小,而利用Update更新的記錄又比較多時,此時就可能需要使用多個重做日志文件來保存這些更改信息。此時就需要進行多次等待才行。那麼就無形之中增加了這個操作的執行時間。所以,經常需要對數據庫進行大容量的更新、刪除或者插入記錄等操作的,最好能夠調整這個重做日志文件的大小,以減少重做日志歸檔的等待時間,提高數據庫的性能。
在調整這個重做日志文件之前,數據庫管理員最好能夠先確認一下,這個重做日志文件歸檔的頻率。如果歸檔的頻率比較高,那麼增加重做日志文件的大小,往往可以明顯的提高數據庫的性能,特別是插入、刪除、更新等操作的效率。那麼該如何來判斷這個重做日志文件歸檔是否頻繁呢?在Oracle數據庫中有比較多的方法。其實重做日志文件就跟普通的文件相同,其也有更新時間等屬性。為此在操作系統上,可以對比幾個重做日志文件的更新時間,來判斷其歸檔的頻率是否頻繁。另外在Oracle數據庫中還有一個動態視圖,名字為v$log_history。在這個視圖中存放著重做日至切換的相關記錄。如數據庫管理員可以查詢最近50個重做日志的切換記錄,看看其相關的時間有多長,從而來判斷這個重做日志的切換是正常的,還是太過於頻繁。一般情況下,只要增加這個重做日志文件的容量,就可以為大批量的更新、刪除等操作提供比較大的重做日志空間。此時執行一個大批量的更新操作時,可能只需要使用一個重做日志文件即可。此時,在重做日志上所花的時間,就是只有產生重做記錄的那部分時間,而沒有重做日志切換歸檔時的等待時間。所以,經過類似的調整之後,往往可以在很大程度上提高數據庫的性能。另外還有一種可行的方法是,不調整重做日志文件的大小,而是增加重做日志文件的數目。如此也可以在頻繁的日志切換過程中提供足夠的日志空間。不過筆者還是傾向與增加重做日志文件的容量來解決這個問題。
不過重做日志文件也並不是越大越好。重做日志文件越大,其歸檔的時間也就越長。俗話說,過之而不及。有時候這反而會給數據庫的安全與性能帶來負面的影響。根據筆者的經驗,筆者認為這個重做日志文件切換的時間間隔最好能夠在30分鐘-40分鐘之間。因為現在即使再復雜的更新或者刪除操作,基本上可以在這個時間內完成。否則的話,可能就是語句方面有問題,需要對SQL語句進行優化。所以將這個日志歸檔的時間間隔確定在這個時間范圍之內是合理的。作為合格的數據庫管理員,需要持續追蹤這個日志切換的時間間隔。可以通過查看兩個連續重做日志文件之間的更新時間間隔或者數據庫系統的日志切換記錄來查看這個日志切換的頻率。
當調整完重做日志文件的大小之後,數據庫管理員仍然需要在一段時間內追蹤這個日志切換的頻率。以判斷調整後的重做日志文件是否能夠實現既定的目標。如果效果不明顯的話,可能還需要再次調整這個重做日志文件的大小。
Oracle數據庫管理員可以使用ALTER DATABASE ADD LOGFILE語句來創建比較大的日志文件。注意此時需要及時將比較小的日志文件刪除。否則的話,大小重做日志文件混用,並不能夠起到預計的效果。為此在調整日志文件大小時一般的步驟就是先創建多個大日志文件,然後再將小日志文件刪除。一般情況下,在刪除小日志文件過程中,最好不要通過刪除重做日志文件組來實現。也就是說,在原有的重做日志文件組下面,建立大的重做日志文件;然後只刪除小的重做日志文件。即重做日志文件組仍然保持不變。改變的只是其內部的重做日志成員而已。
另外在重做日志管理中,如果將重做日志文件放置在性能比較好的硬盤中,或者采用磁盤陣列等技術來提高重做日志文件的寫入速度,也可以提高大批量插入、更新等操作的效率。總之,最好這個日志切換的頻率不要低於30分鐘。如果少於這個時間的話,那麼系統管理員就需要調整日志文件的大小,來延長兩次日志切換之間的時間間隔。當然這個時間間隔需要根據企業應用的變化而變化。