高性能Oracle數(shù)據(jù)庫(kù) 數(shù)據(jù)高速緩存解析
Oracle數(shù)據(jù)庫(kù)作為復(fù)雜運(yùn)算的首選數(shù)據(jù)庫(kù),其首先是通過所謂的數(shù)據(jù)高速緩存來實(shí)現(xiàn)對(duì)數(shù)據(jù)的高速運(yùn)算與操作的。
數(shù)據(jù)高速緩存跟操作系統(tǒng)的緩存類似,其存儲(chǔ)最近從數(shù)據(jù)文件中讀取的數(shù)據(jù)塊,其中的數(shù)據(jù)可以被所有的用戶所訪問。如當(dāng)我們利用Select語句從數(shù)據(jù)庫(kù)中查詢員工信息的時(shí)候,其首先不是從數(shù)據(jù)文件中去查詢這個(gè)數(shù)據(jù),而是從數(shù)據(jù)高速緩存中去查找,而沒有這個(gè)必要再去查詢磁盤中的數(shù)據(jù)文件了。只有在數(shù)據(jù)緩存中沒有這個(gè)數(shù)據(jù)的時(shí)候,數(shù)據(jù)庫(kù)才會(huì)從數(shù)據(jù)文件中去查詢。Oracle數(shù)據(jù)庫(kù)為什么要如此設(shè)計(jì)呢?這是由于數(shù)據(jù)庫(kù)在讀取數(shù)據(jù)的時(shí)候,讀取內(nèi)存的速度比讀取磁盤的速度要快很多倍,所以這種機(jī)制可以提高數(shù)據(jù)的整體訪問效率。
雖然其他數(shù)據(jù)庫(kù)也有這方面的設(shè)計(jì),但是,相對(duì)來說,Oracle數(shù)據(jù)庫(kù)比其他數(shù)據(jù)庫(kù),在這方面有更加出色的表現(xiàn)。難怪Oracle數(shù)據(jù)庫(kù)在內(nèi)存的要求上,比其他數(shù)據(jù)庫(kù)要高。若以稍微的代價(jià)犧牲一些內(nèi)存,而換取更高的數(shù)據(jù)訪問性能。筆者認(rèn)為還是值得的。下面我們就來看看,Oracle數(shù)據(jù)庫(kù)在數(shù)據(jù)高速緩存上有哪些特殊的表現(xiàn)。
一、 空閑緩存塊
當(dāng)我們重新啟動(dòng)數(shù)據(jù)庫(kù)后,系統(tǒng)就會(huì)為數(shù)據(jù)庫(kù)分配一些空閑的緩存塊。空閑緩存塊中是沒有任何數(shù)據(jù)的,他在那邊默默的等著別寫入記錄。當(dāng)Oracle 數(shù)據(jù)庫(kù)從數(shù)據(jù)文件中讀取數(shù)據(jù)后,數(shù)據(jù)庫(kù)就會(huì)尋找是否有空閑的緩存塊,以便將數(shù)據(jù)寫入其中。
一般來說,數(shù)據(jù)庫(kù)在啟動(dòng)的時(shí)候,就會(huì)在內(nèi)存中預(yù)先分配這些緩存塊。所以,Oracle數(shù)據(jù)庫(kù)在啟動(dòng)的時(shí)候,會(huì)占用比較多的內(nèi)存。但是,這可以免去在實(shí)際需要時(shí)向內(nèi)存申請(qǐng)的時(shí)間。所以,有時(shí)候Oracle數(shù)據(jù)庫(kù)雖然已啟動(dòng),內(nèi)存的占用率就很高,但是,其后續(xù)仍然可以正常運(yùn)行的原因。而其他數(shù)據(jù)庫(kù)雖然剛啟動(dòng)的時(shí)候內(nèi)存占用率不是很高,但是,但系統(tǒng)內(nèi)存到達(dá)80%以上時(shí),在進(jìn)行數(shù)據(jù)處理就會(huì)受到明顯的影響。
所以,當(dāng)我們利用SELECT語句從數(shù)據(jù)庫(kù)文件中讀取文件的時(shí)候,數(shù)據(jù)庫(kù)首先會(huì)尋找是否有空閑的緩存。
二、命中緩存塊
當(dāng)SELECT語句先從數(shù)據(jù)庫(kù)文件中讀取數(shù)據(jù)后,會(huì)把取得的數(shù)據(jù)放入到這個(gè)命中緩存塊中。也就是說,當(dāng)我們利用查詢語句從數(shù)據(jù)庫(kù)查詢處員工信息后,這個(gè)信息就會(huì)被保存在高速緩存中。直道高速緩存消耗完畢等原因,這個(gè)空間才會(huì)被釋放。如此的話,下次用戶在查詢員工信息的時(shí)候,就不需要從數(shù)據(jù)庫(kù)文件中再次查詢相關(guān)信息,而直接從數(shù)據(jù)高速緩存中提取數(shù)據(jù),從而提高數(shù)據(jù)庫(kù)的訪問效率。
另外要注意的一個(gè)問題是,命中緩存塊中的數(shù)據(jù)不會(huì)被寫入數(shù)據(jù)文件。確實(shí),這個(gè)命中緩存塊中的數(shù)據(jù)沒有被更改,其當(dāng)然也不會(huì)被寫入數(shù)據(jù)庫(kù)文件中。
三、臟緩存塊
當(dāng)我們利用SELECT查詢語句把員工信息的數(shù)據(jù)查詢出來后,數(shù)據(jù)庫(kù)會(huì)把這個(gè)數(shù)據(jù)所存儲(chǔ)的空緩存塊做標(biāo)記,表示該緩存塊已經(jīng)存有數(shù)據(jù),使命中緩存塊。此時(shí),我們?nèi)粼诶脭?shù)據(jù)更新語句UPDATE對(duì)其中某條記錄進(jìn)行更新時(shí),如要把張三的名字改為張四。運(yùn)行UPDATE語句后,數(shù)據(jù)庫(kù)也首先從高速緩存中查找是否有這條記錄,若存在這條記錄的話,就直接更改這條記錄,并且把該緩存塊標(biāo)記為贓緩存塊。如此的話,就可以保持?jǐn)?shù)據(jù)的一致性。
也就是說,臟緩存塊存儲(chǔ)的是已經(jīng)被修改過的,但是還沒有寫入到數(shù)據(jù)庫(kù)文件的信息。當(dāng)SQL的UPDATE等數(shù)據(jù)更新語句對(duì)某個(gè)緩存塊中的數(shù)據(jù)進(jìn)行更改之后,這個(gè)命中緩存塊就會(huì)被數(shù)據(jù)庫(kù)標(biāo)記為臟緩存塊。當(dāng)滿足一定的條件時(shí),這些臟緩存塊中的數(shù)據(jù)內(nèi)容會(huì)被寫入到數(shù)據(jù)庫(kù)文件中去,以便永久性的保留數(shù)據(jù)庫(kù)修改記錄。 #p#page_title#e#
當(dāng)系統(tǒng)中沒有空閑緩存塊,而用戶又需要查詢數(shù)據(jù)時(shí),數(shù)據(jù)庫(kù)就查詢當(dāng)前所有的臟緩存塊,把最先更改的臟緩存塊中的內(nèi)容先寫入數(shù)據(jù)庫(kù)文件中,以便釋放這個(gè)臟緩存塊。數(shù)據(jù)庫(kù)就又會(huì)把這個(gè)臟緩存塊標(biāo)記為空閑緩存塊,以方便用戶下次存入數(shù)據(jù)。
那Oracle數(shù)據(jù)庫(kù)到底是通過什么手段,來控制空閑緩存塊、命中緩存塊、臟緩存塊之間的相互轉(zhuǎn)換的呢?說出來也許你不相信,Oracle數(shù)據(jù)庫(kù)就是通過兩張表,來管理這么復(fù)雜的功能。這兩張表分別是DIRTY列表與LRU列表。
其中LRU列表保存著所有空閑緩存塊、命中緩存塊已經(jīng)還沒有被移入到DIRTY列表中的臟緩存塊。當(dāng)Oracle數(shù)據(jù)庫(kù)用戶在查詢數(shù)據(jù)的時(shí)候,可能會(huì)遇到如下情況:
1、當(dāng)用戶查找員工信息時(shí),數(shù)據(jù)庫(kù)首先在LRU列表中查詢是否有空閑緩存塊。其查詢的數(shù)據(jù)是從尾部開始查找。當(dāng)查找有空閑的緩存塊時(shí),數(shù)據(jù)庫(kù)就會(huì)把查到的數(shù)據(jù)寫入到這個(gè)空閑緩存中。
2、若數(shù)據(jù)庫(kù)在查詢的時(shí)候,首先查到的是臟緩存的話,則會(huì)把這個(gè)臟緩存移動(dòng)到DIRTY列表中,然后再繼續(xù)查詢,直到查詢到合適的空閑緩存塊為止。
3、若數(shù)據(jù)庫(kù)在LRU列表中,從尾到頭查了一遍,沒有找到空閑緩存塊,或者雖然有空閑緩存塊,但是其容量不符合要求時(shí),數(shù)據(jù)庫(kù)就會(huì)暫時(shí)結(jié)束這一次查找。然后,系統(tǒng)就會(huì)觸發(fā)數(shù)據(jù)庫(kù)寫進(jìn)程,把DIRTY列表中的臟緩存塊寫入到數(shù)據(jù)庫(kù)中去。已經(jīng)被寫入到數(shù)據(jù)庫(kù)文件中去的臟緩存塊將又被數(shù)據(jù)庫(kù)標(biāo)記為空閑緩存塊,并插入到LRU列表中。當(dāng)數(shù)據(jù)庫(kù)執(zhí)行完畢這個(gè)動(dòng)作之后,數(shù)據(jù)庫(kù)又會(huì)對(duì)LRU列表進(jìn)行搜索,找到合適的數(shù)據(jù)高速空閑緩存之后,就會(huì)把讀取的數(shù)據(jù)寫入到這個(gè)空閑緩存中。所以,我們?cè)诶脭?shù)據(jù)庫(kù)的時(shí)候,會(huì)發(fā)現(xiàn)有時(shí)候讀取大量數(shù)據(jù)的時(shí)候,速度會(huì)比較慢。除了其他原因外,也有一部份原因是因?yàn)閿?shù)據(jù)庫(kù)沒有查到足夠大的空閑緩存在存放這些數(shù)據(jù),故只好寫進(jìn)行讀寫操作,以釋放更多的臟緩存,然后再進(jìn)行查詢操作。
知道了這些數(shù)據(jù)庫(kù)高速緩存工作原理之后,我們數(shù)據(jù)庫(kù)管理員又該做些什么呢,來對(duì)Oracle數(shù)據(jù)庫(kù)進(jìn)行優(yōu)化。為此,筆者有以下建議:
1、為Oracle數(shù)據(jù)庫(kù)配置盡量大的內(nèi)存。Oracle數(shù)據(jù)庫(kù)最新版本,根據(jù)官方的建議,其內(nèi)存需要1G。雖然在低于這個(gè)內(nèi)存數(shù)量的時(shí)候,數(shù)據(jù)庫(kù)仍然可以運(yùn)行,但是,其運(yùn)行適度會(huì)大打折扣。當(dāng)查詢大量數(shù)據(jù)的時(shí)候,更是比較吃力。筆者現(xiàn)在使用的數(shù)據(jù)庫(kù)服務(wù)器,是使用了4個(gè)G的內(nèi)存。以前我用的是2個(gè)G的。內(nèi)存升級(jí)后,發(fā)現(xiàn)數(shù)據(jù)庫(kù)的性能得到了比較大的改善。
2、在對(duì)數(shù)據(jù)進(jìn)行查詢操作時(shí),盡量使用限制條件。如現(xiàn)在需要查詢銷售部門的員工信息時(shí),我們不需要查詢?nèi)康膯T工信息,而是在SELECT語句中,利用WHERE條件語句設(shè)置查詢條件。如此的話,就可以充分利用DIRTY列表中的空閑緩存塊,而不會(huì)因?yàn)榭臻e緩存塊容量不夠而頻繁的去執(zhí)行數(shù)據(jù)庫(kù)寫操作。這會(huì)明顯降低數(shù)據(jù)庫(kù)的運(yùn)行操作。同時(shí),在查詢時(shí),最好也能夠明確查詢的信息,如你只需要員工的姓名與入職日期,那就不需要把員工的出生年月、身份證號(hào)碼都查詢出來。所以,有時(shí)候合理設(shè)計(jì)視圖,也可以提高數(shù)據(jù)庫(kù)的運(yùn)行效率。
3、最好不要在數(shù)據(jù)庫(kù)服務(wù)器上運(yùn)行其他的服務(wù)。在數(shù)據(jù)庫(kù)服務(wù)器中,若還運(yùn)行其它服務(wù)器的話,除了硬件資源爭(zhēng)奪影響服務(wù)器的運(yùn)行效率之外,還會(huì)產(chǎn)生一個(gè)問題。就是會(huì)使得數(shù)據(jù)庫(kù)的數(shù)據(jù)高速緩存塊不連續(xù)。這會(huì)直接影響數(shù)據(jù)庫(kù)查詢空閑緩存塊的效率。對(duì)臟緩存塊進(jìn)行數(shù)據(jù)庫(kù)寫入操作以及數(shù)據(jù)庫(kù)進(jìn)行標(biāo)記之間的轉(zhuǎn)換也會(huì)產(chǎn)生影響。所以,根據(jù)筆者的經(jīng)驗(yàn),數(shù)據(jù)庫(kù)服務(wù)器最好能夠獨(dú)立。最多只能跟其對(duì)應(yīng)的應(yīng)用服務(wù)器部署在同一臺(tái)服務(wù)器上。如現(xiàn)在Oracle數(shù)據(jù)庫(kù)是一臺(tái)ERP系統(tǒng)的后臺(tái)數(shù)據(jù)庫(kù),最好數(shù)據(jù)庫(kù)能夠跟ERP服務(wù)器分開部署。但是,若由于服務(wù)器資金的限制,那么可以把ERP應(yīng)用服務(wù)器跟數(shù)據(jù)庫(kù)服務(wù)器部署在一臺(tái)服務(wù)器上。但是,不能再跟郵件服務(wù)器等應(yīng)用服務(wù)器放在一起。這會(huì)影響數(shù)據(jù)高速緩存的管理效率,從而最終影響數(shù)據(jù)庫(kù)的運(yùn)行效能。現(xiàn)在服務(wù)器價(jià)格逐漸下滑,服務(wù)器的成本已經(jīng)不是影響企業(yè)數(shù)據(jù)庫(kù)應(yīng)用的關(guān)鍵。所以,出于數(shù)據(jù)庫(kù)性能考慮,筆者認(rèn)為,企業(yè)在這上面還是應(yīng)該大方的進(jìn)行投資。沒必要為了這么一點(diǎn)點(diǎn)錢,影響到數(shù)據(jù)庫(kù)的性能。 #p#page_title#e#