全局臨時表 (GTT, Global Temporary Table):表定義持久化存儲於數據字典,**資料僅在會話或事務生命周期內可見**,會話結束或提交/回滾時自動清空(TRUNCATE 機制),不產生 Redo/Undo(僅產生極少量元數據 Redo)。
| 模式 | DDL 語法 | 資料可見範圍 | 清空時機 | 典型場景 |
|---|---|---|---|---|
| 事務級 | ON COMMIT DELETE ROWS | 當前事務 | COMMIT / ROLLBACK | 複雜報表中間結果、多步驟 ETL 暫存 |
| 會話級 | ON COMMIT PRESERVE ROWS | 當前會話 | 會話斷開 / DISCONNECT | 用戶購物車、跨頁面暫存、PL/SQL 集合替代 |
-- 事務級 CREATE GLOBAL TEMPORARY TABLE gtt_txn ( id NUMBER, process_date DATE, status VARCHAR2(20) ) ON COMMIT DELETE ROWS; -- 會話級 CREATE GLOBAL TEMPORARY TABLE gtt_sess ( user_id NUMBER, cart_items CLOB, updated_at TIMESTAMP ) ON COMMIT PRESERVE ROWS;
DBMS_STATS.GATHER_TABLE_STATS,12c+ 支援會話級統計)EXP/IMP/DATAPUMP 匯出定義(資料不匯出)@dblink 不可見)FLASHBACK TABLE、FLASHBACK QUERY-- 會話 1 INSERT INTO gtt_sess VALUES (1, 'item_a', SYSTIMESTAMP); COMMIT; SELECT * FROM gtt_sess; -- 返回 1 行 -- 會話 2 (新連線) SELECT * FROM gtt_sess; -- 返回 0 行,完全隔離
GTT 無共享統計,預設使用動態採樣。12c 引入 會話級私有統計:
-- 12c+ 為當前會話收集統計 EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=>USER, tabname=>'GTT_SESS', scope=>'SESSION'); -- 查看私有統計 SELECT * FROM USER_TAB_STATISTICS WHERE TABLE_NAME='GTT_SESS';
建議:複雜查詢前在會話中收集一次統計,避免動態採樣誤導優化器。
| 維度 | Oracle GTT | SQL Server |
|---|---|---|
| 定義持久性 | 永久(DDL 字典存儲) | 本地 #temp 隨會話銷毀;全局 ##temp 隨最後會話銷毀 |
| 儲存層 | 臨時表空間(磁碟) | tempdb(記憶體優先,溢寫磁碟) |
| 事務級隔離 | 原生支援 ON COMMIT DELETE ROWS | 無對應機制,需手動 DELETE |
| 跨會話共享 | 不可見(定義共享,資料隔離) | 全局 ##temp 可跨會話共享資料 |
| 頻繁建刪效能 | 極高(僅字典操作) | 頻繁 CREATE/DROP 易導致 tempdb 爭用、系統表膨脹 |
GTT_<業務>_ 區分生命周期INSERT 開銷SCOPE=>'SESSION';11g 依賴動態採樣 OPTIMIZER_DYNAMIC_SAMPLING=4WITH 子查詢物化,可控制溢寫臨時表空間Oracle GTT 以「定義永久、資料暫態」設計完美平衡了效能與隔離性。**事務級 (ON COMMIT DELETE ROWS) 為預設最佳選擇**,除非確有跨事務共享需求。12c 私有統計功能大幅提升複雜報表查詢穩定性,建議升級利用。