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