oracle 臨時表的應用
Temp Table 的特點:
(1) 多用戶操作的獨立性:對于使用同一張臨時表的不同用戶,ORACLE都會分配一個獨立的 Temp Segment,這樣就避免了多個用戶在對同一張臨時表操作時發生交叉,從而保證了多個用戶操作的并發性和獨立性;
(2) 數據的臨時性:既然是臨時表,顧名思義,存放在該表中的數據是臨時性的。ORACLE根據你創建臨時表時指定的參數(On Commit Delete Rows / On Commit Preserve Rows),自動將數據TRUNCATE掉。
Temp Table 數據的時效性:
(1)On Commit Delete Rows: 數據在 Transaction 期間有效,一旦COMMIT后,數據就被自動 TRUNCATE 掉了;
SQL> CREATE GLOBAL TEMPORARY TABLE QCUI_Temp_Trans
2 ON COMMIT DELETE ROWS
3 AS
4 SELECT * FROM t_Department;
表已創建。
SQL> INSERT INTO QCUI_Temp_Trans
2 SELECT * FROM t_Dept;
已創建4行。
SQL> SELECT * FROM QCUI_Temp_Trans;
DEPTID DEPTNAME
---------- --------------------
101 銷售部
201 財務部
301 貨運部
401 采購部
SQL> commit;
提交完成。
SQL> SELECT * FROM QCUI_Temp_Trans;
未選定行
(2)On Commit Preserve Rows :數據在 Session 期間有效,一旦關閉了Session 或 Log Off 后,數據就被 ORACLE 自動 Truncate 掉。
SQL> CREATE GLOBAL TEMPORARY TABLE QCUI_Temp_Sess
2 ON COMMIT PRESERVE ROWS
3 AS
4 SELECT * FROM t_Department;
表已創建。
SQL> Select * from QCUI_Temp_Sess;
DEPTID DEPTNAME
---------- --------------------
101 銷售部
301 貨運部
401 采購部
201 財務部
SQL> exit
C:\Documents and Settings\QCUI>sqlplus sqltrainer@ibm
SQL> SELECT * FROM QCUI_Temp_Sess;
未選定行
注:這里要說明的是,ORACLE Truncate 掉的數據僅僅是分配給不同 Session 或 Transaction的 Temp Segment 上的數據,而不是將整張表數據 TRUNCATE 掉。
Temp Table 的應用:
Temp Table 就我理解而言,主要有兩方面應用。
對于一個電子商務類網站,不同消費者在網站上購物,就是一個獨立的 SESSION,選購商品放進購物車中,最后將購物車中的商品進行結算。也就是說,必須在整個SESSION期間保存購物車中的信息。同時,還存在有些消費者,往往最終結賬時放棄購買商品。如果,直接將消費者選購信息存放在最終表(PERMANENT)中,必然對最終表造成非常大的壓力。
因此,對于這種案例,就可以采用創建臨時表( ON COMMIT PRESERVE ROWS )的方法來解決。數據只在 SESSION 期間有效,對于結算成功的有效數據,轉移到最終表中后,ORACLE自動TRUNCATE 臨時數據;對于放棄結算的數據,ORACLE 同樣自動進行 TRUNCATE ,而無須編碼控制,并且最終表只處理有效訂單,減輕了頻繁的DML的壓力。
注:這里似乎說得不對,對于B/S應用,雖然SESSION是一個,但此session并不是數據庫連接的session,每次頁面請求都是使用新的連接(或從連接池中獲取的),對于數據庫而言是新的session,這種情況下,臨時表內的數據是不是不能共享呀??
wallimn 2009-11-11
Temp Table 的另一個應用,就是存放數據分析的中間數據。
Temp Table 存放在哪兒?
Temp Table 并非存放在用戶的表空間中,而是存放在 Schema 所指定的臨時表空間中。
SQL> Select Table_Name, Tablespace_Name
2 From User_Tables
3 Where Table_Name Like 'QCUI%';
TABLE_NAME TABLESPACE_NAME
------------------------------ ------------------------------
QCUI_TEMP_SESS
QCUI_TEMP_TRANS
可見這兩張臨時表并未存放在用戶的表空間中。
用戶 SQLTRAINER 的臨時表空間是 TEMP , 用戶創建的臨時表是存放在TEMP表空間中的。下面來證明
SQL> SELECT UserName, Default_Tablespace def_ts, Temporary_Tablespace temp_ts
2 FROM User_Users;
USERNAME DEF_TS TEMP_TS
----------------------------- ------------------ ----------
SQLTRAINER ts_ORASQLTraining TEMP
SQL> connect system/manager@ibm
已連接。
SQL> alter tablespace temp offline;
表空間已更改。
SQL> connect sqltrainer/sqltrainer@ibm
已連接。
SQL> INSERT INTO QCUI_Temp_Sess
2 SELECT * FROM t_Department;
INSERT INTO QCUI_Temp_Sess
*
ERROR 位于第 1 行:
ORA-01542: 表空間'TEMP'脫機,無法在其中分配空間
對 Temp Table 的 DML 操作是否不產生 Redo Log ?
盡管對臨時表的DML操作速度比較快,但同樣也是要產生 Redo Log 的,只是同樣的DML語句,比對 PERMANENT 的DML 產生的Redo Log 少。
SQL> Set AutoTrace On
SQL> CREATE GLOBAL TEMPORARY TABLE QCUI_Temp_Sess_AllObj
2 ON COMMIT PRESERVE ROWS
3 AS
4 SELECT * FROM All_Objects;
表已創建。
SQL> INSERT INTO QCUI_Temp_Sess_AllObj
2 SELECT * FROM All_Objects;
已創建21839行。
Statistics
---------------------------------------------------------
……
168772 redo size
……
SQL> CREATE TABLE QCUI_ALL_OBJECTS
2 AS
3 SELECT * FROM All_Objects
4 WHERE 1 = 0;
表已創建。
SQL> INSERT INTO QCUI_All_Objects
2 SELECT * FROM ALL_Objects;
已創建21839行。
Statistics
----------------------------------------------------------
……
2439044 redo size
……
posted on 2009-11-22 08:53 gdufo 閱讀(367) 評論(0) 編輯 收藏 所屬分類: Database (oracle, sqlser,MYSQL)