如果使用者查詢時,使用Order BY排序語句指定按員工編號來排序,那麼排序後產生的所有記錄就是臨時資料。對於這些臨時資料,Oracle資料庫是如何處理的呢?
通常情況下,Oracle資料庫會先將這些臨時資料存放到記憶體的PGA(程式全域區)內。在這個程式全域區中有一個叫做排序區的地方,專門用來存放這些因為排序操作而產生的臨時資料。但是這個分區的容量是有限的。當這個分區的大小不足以容納排序後所產生的記錄時,資料庫系統就會將臨時資料存放到暫存資料表空間中。這就是暫存資料表空間的來曆。看起來好像這個暫存資料表空間是個臨時工,對於資料庫的影響不會有多大。其實大家這是誤解這個暫存資料表空間了。在使用者進行資料庫操作時,排序、分組匯總、索引這些作業是少不了,其會產生大量的臨時資料。為此基本上每個資料庫都需要用到暫存資料表空間。而如果這個暫存資料表空間設定不當的話,則會給資料庫效能帶來很大的負面影響。為此管理員在維護這個暫存資料表空間的時候,不能夠掉以輕心。要避免因為暫存資料表空間設定不當影響資料庫的效能。具體來說,主要需要注意如下幾個方面的內容。
一、建立使用者時要記得為使用者建立暫存資料表空間。
最好在建立使用者時為使用者指定暫存資料表空間。如可以利用語句default temporary table space語句來為資料庫設定預設的暫存資料表空間。不過在Oracle資料庫中這個不是強制的。但是筆者強烈建議這麼做。因為如果沒有為使用者指定預設暫存資料表空間的話,那麼當這個使用者因為排序等操作需要使用到暫存資料表空間的話,資料庫系統就會“自作聰明”的利用系統資料表空間SYSTEM來建立臨時段。眾所周知,這是一個系統資料表空間。由於在這個資料表空間中存放著系統運行相關的資料,一般的建議是使用者的資料不能夠儲存在這個資料表空間中。那麼如果將使用者的暫存資料表空間防止在這個系統資料表空間之內,會產生什麼負面影響呢?
由於暫存資料表空間中的資料是臨時的。為此資料庫系統需要頻繁的分配和釋放臨時段。這些頻繁的操作會在系統資料表空間中產生大量的儲存片段。當這些儲存片段比較多時,就會影響系統讀取硬碟的效率,從而影響資料庫的效能。其次系統資料表空間的大小往往是有限制的。此時臨時段也來插一腳,就會佔用系統資料表空間的大小。
為此資料庫管理員需要注意一點,當沒有為使用者指定暫存資料表空間時,使用者排序等操作仍然需要用到臨時段。此時資料庫系統就會將臨時段放入到系統資料表空間中。為此就會對資料庫的效能產生不利的影響。所以筆者建議各位讀者與資料庫管理員,在建立使用者的時候同時為使用者指定一個預設的資料表空間,以減少臨時段對系統資料表空間的佔用。
二、合理設定PGA,減少暫存資料表空間使用的幾率。
總之,如果臨時段被頻繁使用的話,由於記憶體與硬碟在效能上的差異,從而會降低資料庫的效能。為此在平時工作中,資料庫管理員還需要監控暫存資料表空間的使用方式,以判斷是否需要採取措施來減少暫存資料表空間的使用來提高資料庫的查詢效能。為了實現這個目的,筆者建議資料庫管理員可以查看v$sort_segment這張動態效能檢視。通過這張動態效能檢視可以查看系統排序段(臨時段的一種)的使用方式。另外通過動態效能檢視v$sort_usage還可以查詢使用排序段的使用者與會話資訊。從而為資料庫管理員最佳化資料庫效能提供資料上的支援。對於這個排序段,筆者還要說明一點。對於排序段來說,同一個常式的所有SQL語句(如果需要排序操作的話)都將共用同一個排序段。並且排序段在第一次需要用到時被建立。排序完成後這個排序段不會被釋放,只有在這個曆程關閉後排序段才會被釋放。為此以上兩張視圖要綜合起來分析,才能夠得到資料庫管理員想要的資訊。
三、要為暫存資料表空間保留足夠的硬碟空間。
其他資料表空間對應的資料檔案,在其建立時就會被完全分配和初始化,即在其建立時就會被分配儲存空間。但是暫存資料表空間對應的臨時檔案則不同。如在Linux作業系統中,暫存資料表空間建立時系統是不會分配和初始化臨時檔案的。也就是說,不會為臨時檔案分配儲存空間。只有臨時資料出現需要用到臨時檔案的時候,系統才會在硬碟上分配一塊地方用來儲存臨時檔案。此時就可能會產生一個問題,即當需要用到臨時檔案系統為其分配空間的時候,才會先系統磁碟分割中沒有足夠的儲存空間了。此時就會產生一些難以預料的後果。
為此對於這些臨時檔案,資料庫管理員最好能夠預先為其保留足夠的空間。如在Linux作業系統中,可以將其防止在一個獨立的分區內,不允許其他應用程式使用。如此的話,就不用擔心臨時檔案沒有地方儲存了。另外由於暫存資料表空間主要用來存放一些排序用的臨時檔案。為此如果能夠將這個暫存資料表空間存放在效能比較好的分區中,還可以提高資料庫系統讀取暫存資料表空間中資料的速度。另外由於系統需要頻繁分配暫存資料表空間中的資料,為此暫存資料表空間所在的分區會出現比較多的片段。此時如果將暫存資料表空間存放在一個獨立的分區內,那麼資料庫管理員就可以單獨對這個分區進行磁碟重組,從而提高這個分區的效能。所以無論出於什麼原因,將暫存資料表空間防止在一個獨立的分區內,是一個不錯的想法。不僅可以保證臨時檔案有儲存的空間,而且還可以提高資料庫的效能。
對於暫存資料表空間最後需要說明的是,預設情況下這個暫存資料表空間對各個使用者都是共用的。也就是說每個串連到資料庫的使用者都可以使用預設的暫存資料表空間。資料庫管理員可以為其指定其他的暫存資料表空間。一般來說,只需要一個暫存資料表空間即可
當排序操作產生臨時資料時,資料庫並不是馬上將其儲存在暫存資料表空間中。通常情況下,會先將這些臨時資料存放區在記憶體的PGA程式全域區內。只有當這個程式全域區無法容納全部資料時,資料庫系統才會啟用暫存資料表空間中的臨時段來儲存這些資料。但是眾所周知,作業系統從記憶體中讀取資料要比從硬碟中讀取資料區塊幾千倍。為此比較理想的情況是,這個程式全域區足夠的大,可以容納所有的臨時資料。此時資料庫系統就永遠用不到暫存資料表空間了。從而可以提高資料庫的效能。
但是這畢竟只是一個理想。由於記憶體大小等多方面的限制,這個PGA程式區的大小往往是有限制的。所以在進行一些大型的排序操作時,這個暫存資料表空間仍然少不了。現在資料庫管理員可以做的就是合理設定這個PGA程式全域區的大小,盡量減少暫存資料表空間使用的幾率。如在實際工作中,資料庫管理員可以根據需要來設定初始化參數SORT_AREA_SIZE參數。這個參數主要控制這個PGA程式全域區內排序區的大小。通常情況下,如果這個資料庫系統主要用來查詢並且需要大量的排序、分組匯總、索引等操作時,那麼可以適當調整這個參數,來擴大PGA分區的大小。相反,如果這個系統主要用於更新操作,或者在這個資料庫伺服器上還部署由其他的應用程式,那麼這個PGA分區就不能夠佔用太多的記憶體,以防止對其他應用程式產生不利的影響。所以說,資料庫官員不能夠一刀切,需要根據實際情況來調整。在必要的情況下,可以增加系統記憶體來增加PGA分區的大小,從而降低暫存資料表空間的使用幾率,以提高資料庫的排序、分組匯總等操作的效能。