在Oracle數據庫中進行排序、分組彙總、索引等到做時,會產生不少的臨時數據。若有一張員工信息表,數據庫中是安裝記錄創建的時間來保存的。若是用戶查詢時,使用Order BY排序語句指定按員工編號來排序,那麼排序後產生的全部記錄就是臨時數據。對於這些臨時數據,Oracle數據庫是如何處理的呢?
一般狀況下,Oracle數據庫會先將這些臨時數據存放到內存的PGA(程序全局區)內。在這個程序全局區中有一個叫作排序區的地方,專門用來存放這些由於排序操做而產生的臨時數據。可是這個分區的容量是有限的。當這個分區的大小不足以容納排序後所產生的記錄時,數據庫系統就會將臨時數據存放到臨時表空間中。這就是臨時表空間的來歷。看起來好像這個臨時表空間是個臨時工,對於數據庫的影響不會有多大。其實你們這是誤解這個臨時表空間了。在用戶進行數據庫操做時,排序、分組彙總、索引這些做業是少不了,其會產生大量的臨時數據。爲此基本上每一個數據庫都須要用到臨時表空間。而若是這個臨時表空間設置不當的話,則會給數據庫性能帶來很大的負面影響。爲此管理員在維護這個臨時表空間的時候,不可以掉以輕心。要避免由於臨時表空間設置不當影響數據庫的性能。具體來講,主要須要注意以下幾個方面的內容。數據庫
建立用戶時要記得爲用戶建立臨時表空間 最好在建立用戶時爲用戶指定臨時表空間。如能夠利用語句default temporary table space語句來爲數據庫設置默認的臨時表空間。不過在Oracle數據庫中這個不是強制的。可是筆者強烈建議這麼作。由於若是沒有爲用戶指定默認臨時表空間的話,那麼當這個用戶由於排序等操做須要使用到臨時表空間的話,數據庫系統就會「自做聰明」的利用系統表空間SYSTEM來建立臨時段。衆所周知,這是一個系統表空間。因爲在這個表空間中存放着系統運行相關的數據,通常的建議是用戶的數據不可以保存在這個表空間中。那麼若是將用戶的臨時表空間防止在這個系統表空間以內,會產生什麼負面影響呢?
因爲臨時表空間中的數據是臨時的。爲此數據庫系統須要頻繁的分配和釋放臨時段。這些頻繁的操做會在系統表空間中產生大量的存儲碎片。當這些存儲碎片比較多時,就會影響系統讀取硬盤的效率,從而影響數據庫的性能。其次系統表空間的大小每每是有限制的。此時臨時段也來插一腳,就會佔用系統表空間的大小。
爲此數據庫管理員須要注意一點,當沒有爲用戶指定臨時表空間時,用戶排序等操做仍然須要用到臨時段。此時數據庫系統就會將臨時段放入到系統表空間中。爲此就會對數據庫的性能產生不利的影響。因此筆者建議各位讀者與數據庫管理員,在建立用戶的時候同時爲用戶指定一個默認的表空間,以減小臨時段對系統表空間的佔用。
合理設置PGA,減小臨時表空間使用的概率 總之,若是臨時段被頻繁使用的話,因爲內存與硬盤在性能上的差別,從而會下降數據庫的性能。爲此在平時工做中,數據庫管理員還須要監控臨時表空間的使用狀況,以判斷是否須要採起措施來減小臨時表空間的使用來提升數據庫的查詢性能。爲了實現這個目的,筆者建議數據庫管理員能夠查看v0_segment這張動態性能視圖。經過這張動態性能視圖能夠查看系統排序段(臨時段的一種)的使用狀況。另外經過動態性能視圖v0_usage還能夠查詢使用排序段的用戶與會話信息。從而爲數據庫管理員優化數據庫性能提供數據上的支持。對於這個排序段,筆者還要說明一點。對於排序段來講,同一個例程的全部SQL語句(若是須要排序操做的話)都將共享同一個排序段。而且排序段在第一次須要用到時被建立。排序完成後這個排序段不會被釋放,只有在這個歷程關閉後排序段纔會被釋放。爲此以上兩張視圖要綜合起來分析,纔可以獲得數據庫管理員想要的信息。
要爲臨時表空間保留足夠的硬盤空間 其餘表空間對應的數據文件,在其建立時就會被徹底分配和初始化,即在其建立時就會被分配存儲空間。可是臨時表空間對應的臨時文件則不一樣。如在Linux操做系統中,臨時表空間建立時系統是不會分配和初始化臨時文件的。也就是說,不會爲臨時文件分配存儲空間。只有臨時數據出現須要用到臨時文件的時候,系統纔會在硬盤上分配一塊地方用來保存臨時文件。此時就可能會產生一個問題,即當須要用到臨時文件系統爲其分配空間的時候,纔會先系統分區中沒有足夠的存儲空間了。此時就會產生一些難以預料的後果。
爲此對於這些臨時文件,數據庫管理員最好可以預先爲其保留足夠的空間。如在Linux操做系統中,能夠將其防止在一個獨立的分區內,不容許其餘應用程序使用。如此的話,就不用擔憂臨時文件沒有地方存儲了。另外因爲臨時表空間主要用來存放一些排序用的臨時文件。爲此若是可以將這個臨時表空間存放在性能比較好的分區中,還能夠提升數據庫系統讀取臨時表空間中數據的速度。另外因爲系統須要頻繁分配臨時表空間中的數據,爲此臨時表空間所在的分區會出現比較多的碎片。此時若是將臨時表空間存放在一個獨立的分區內,那麼數據庫管理員就能夠單獨對這個分區進行碎片整理,從而提升這個分區的性能。因此不管出於什麼緣由,將臨時表空間防止在一個獨立的分區內,是一個不錯的想法。不只能夠保證臨時文件有存儲的空間,並且還能夠提升數據庫的性能。
對於臨時表空間最後須要說明的是,默認狀況下這個臨時表空間對各個用戶都是共享的。也就是說每一個鏈接到數據庫的用戶均可以使用默認的臨時表空間。數據庫管理員能夠爲其指定其餘的臨時表空間。通常來講,只須要一個臨時表空間便可
當排序操做產生臨時數據時,數據庫並非立刻將其存儲在臨時表空間中。一般狀況下,會先將這些臨時數據存儲在內存的PGA程序全局區內。只有當這個程序全局區沒法容納所有數據時,數據庫系統纔會啓用臨時表空間中的臨時段來保存這些數據。可是衆所周知,操做系統從內存中讀取數據要比從硬盤中讀取數據塊幾千倍。爲此比較理想的狀況是,這個程序全局區足夠的大,能夠容納全部的臨時數據。此時數據庫系統就永遠用不到臨時表空間了。從而能夠提升數據庫的性能。
可是這畢竟只是一個理想。因爲內存大小等多方面的限制,這個PGA程序區的大小每每是有限制的。因此在進行一些大型的排序操做時,這個臨時表空間仍然少不了。如今數據庫管理員能夠作的就是合理設置這個PGA程序全局區的大小,儘可能減小臨時表空間使用的概率。如在實際工做中,數據庫管理員能夠根據須要來設置初始化參數SORT_AREA_SIZE參數。這個參數主要控制這個PGA程序全局區內排序區的大小。一般狀況下,若是這個數據庫系統主要用來查詢而且須要大量的排序、分組彙總、索引等操做時,那麼能夠適當調整這個參數,來擴大PGA分區的大小。相反,若是這個系統主要用於更新操做,或者在這個數據庫服務器上還部署由其餘的應用程序,那麼這個PGA分區就不可以佔用太多的內存,以防止對其餘應用程序產生不利的影響。因此說,數據庫官員不可以一刀切,須要根據實際狀況來調整。在必要的狀況下,能夠增長系統內存來增長PGA分區的大小,從而下降臨時表空間的使用概率,以提升數據庫的排序、分組彙總等操做的性能。