在Oracle數據庫中進行order by or group by、索引的創建和重創建、distinct操作、union & intersect & minus sort-merge joins、Analyze 操作、異常等操作時,會產生很多的臨時數據。如有一張員工信息表,數據庫中是安裝記錄建立的時間來保存的。如果用戶查詢時,使用Order BY排序語句指定按員工編號來排序,那么排序后產生的所有記錄就是臨時數據。通常情況下,Oracle數據庫會先將這些臨時數據存放到內存的PGA(程序全局區)內。如果數據量太大,PGA存不了,則會放入臨時表空間。
默認情況下,臨時表空間對所有用戶是共享的。當然可以為特殊用戶指定單獨的臨時表空間。臨時表空間可以重用。
當臨時表空間不足的時候,就會報:ORA-01652:無法通過128(在表空間TEMP中)擴展temp段
這個時候,想當然的就想看看臨時表空間的使用情況了:
select tablespace_name, bytes, user_bytes, user_bytes/bytes,file_name from dba_temp_files;
99%?但是其實這個使用率並沒有太大的意義,因為當新增一個臨時文件(如TEMP02.DBF),然后再跑一次order by,這個使用率就直接飆到99%了。然后換其他的order by語句測試,發現還是可以正常查出數據,說明臨時表空間的使用率跟正常的表空間使用率,有所不一樣(具體怎么個不一樣,就不得而知了)。
也就是說,報錯的時候,它的使用率可能是99%;正常運行的時候,使用率也可能是99%。
當報錯的時候,就說明臨時表空間真的不足了。但由於臨時表空間表現為的是dbf文件,那擴展空間也就方便多了。可以直接增大原臨時文件,還可以增加臨時文件以達到擴大臨時表空間的目的。如果你的臨時表空間滿得太快,這種方式就治標不治本了。可以通過v$sort_usage和v$sort_segment兩個視圖,分析出是哪些用戶和哪些sql導致臨時表空間暴漲,再針對性解決。除此之外,優化sql以及對查詢的字段建立索引,也可以減少臨時表空間的占用。在Oracle中,如果表沒有索引,那么會將所有的數據都復制到臨時表空間,而如果有索引的話,一般只是將索引的數據復制到臨時表空間中。
除了以上這種臨時表空間真正滿了的情況,查詢會報錯以外,還有一種情況,也會報同樣的錯,那就是臨時文件offline了。
在v_$tempfile視圖中,記錄了臨時文件的狀態,一種是online,一種是offline。當狀態為offline的時候,查詢也有可能會報這個錯。
當然,如果一個臨時文件offline了,查詢大小時,也是查不出來的。
與臨時表空間相關的語句: