當 Oracle 資料庫支撐的應用系統面臨百萬級以上的龐大資料量,且涉及多張大表聯結時,若發現某幾張大表聯結後的結果集極小,且取得該結果集的速度很快,此時引入「全域暫存表」往往能事半功倍。
全域暫存表的定義對所有 Session 可見,但資料具有隔離性:每個 Session 只能看見自己插入的資料。表結構持久存在,資料則隨 Session 或 Transaction 結束自動清除,不佔用永久表空間,預設儲存於 TEMP 表空間,大幅降低 I/O 爭用。
| 類型 | 語法關鍵字 | 資料保留時機 | 適用場景 |
|---|---|---|---|
| Session 級 | ON COMMIT PRESERVE ROWS | Session 結束時截斷 | 跨多個 Transaction 需共用暫存資料 |
| Transaction 級 | ON COMMIT DELETE ROWS | Commit/Rollback 時截斷 | 單一 Transaction 內的中繼運算結果 |
-- Session 級暫存表 CREATE GLOBAL TEMPORARY TABLE tmp_student ( stu_id NUMBER(5), class_id NUMBER(5), stu_name VARCHAR2(8), stu_memo VARCHAR2(200) ) ON COMMIT PRESERVE ROWS; -- Transaction 級暫存表 CREATE GLOBAL TEMPORARY TABLE tmp_class ( class_id NUMBER(5), class_name VARCHAR2(8), class_memo VARCHAR2(200) ) ON COMMIT DELETE ROWS;
以下示範 Session 級暫存表的資料生命週期:
INSERT INTO tmp_student VALUES (1, 1, '張三', '福建'); INSERT INTO tmp_student VALUES (2, 1, '劉德華', '福州'); COMMIT; -- Session 級:Commit 後資料仍保留 SELECT * FROM tmp_student; -- 可見 2 筆 INSERT INTO tmp_student VALUES (3, 2, 'S.H.E', '廈門'); ROLLBACK; -- Session 級:Rollback 只會移回未 Commit 的那一筆 SELECT * FROM tmp_student; -- 仍可見前 2 筆
善用全域暫存表,能將「大表聯結大表」轉化為「大表過濾→暫存表→小表聯結」,顯著降低邏輯讀與 Temp 空間壓力,是大型報表與 ETL 流程的常用優化手段。