兩大類型回顧
| 特性 | 會話級 (PRESERVE ROWS) | 事務級 (DELETE ROWS) |
| 數據清空時機 | 會話結束 | COMMIT/ROLLBACK/會話結束 |
| 跨事務保留 | 是 | 否 |
| 適用場景 | 報表中間表、多步驟向導暫存 | 單事務 ETL 中間結果 |
| 統計信息 (12c+) | 會話級私有統計 | 會話級私有統計 |
創建語法
-- 會話級
CREATE GLOBAL TEMPORARY TABLE gtt_session (
id NUMBER, data VARCHAR2(100)
) ON COMMIT PRESERVE ROWS;
-- 事務級
CREATE GLOBAL TEMPORARY TABLE gtt_txn (
id NUMBER, data VARCHAR2(100)
) ON COMMIT DELETE ROWS;
四大原生不足與規避方案
| 不足 | 影響 | 規避/替代方案 |
| 不支持 LOB (BLOB/CLOB/NCLOB) | 無法暫存大文本/二進制 | 1) 自建臨時表 + LOB 列 2) 12c+ PRIVATE TEMPORARY TABLE (ORA$PTT_*) 支持 LOB |
| 不支持外鍵/主鍵約束 | 無法聲明式完整性 | 應用層邏輯控制;或自建表 + 觸發器模擬 |
| 無法收集持久統計 (11g-) | 執行計劃可能不優 | 12c+ DBMS_STATS.GATHER_TABLE_STATS(..., SCOPE=>'SESSION');11g 用動態採樣 OPT_ESTIMATE Hint |
| DDL 鎖定 (創建/截斷需排他庫緩存鎖) | 高併發創建/清空爭用 | 預先創建好,運行期只 INSERT/TRUNCATE;或用連接池預熱 |
何時使用 GTT (決策樹)
- 中間結果無需持久化,會話/事務結束自動清理 → GTT 首選。
- 涉及 LOB/外鍵/持久統計 → 自建臨時表方案。
- 數據量極大 (>100萬行) 且需並行查詢 → 分區表 + 定期 TRUNCATE 分區,或 In-Memory 列存儲。
自建擴展臨時表方案 (彌補原生不足)
-- 1. 物理表 + SESSION_ID 區分會話
CREATE TABLE my_gtt_session (
session_id RAW(16) DEFAULT SYS_CONTEXT('USERENV','SID'),
id NUMBER,
data CLOB, -- 支持 LOB
CONSTRAINT pk_my_gtt PRIMARY KEY (session_id, id)
);
-- 2. 登出觸發器自動清理
CREATE OR REPLACE TRIGGER trg_cleanup_my_gtt
AFTER LOGOFF ON DATABASE
DECLARE
v_sid RAW(16) := SYS_CONTEXT('USERENV','SID');
BEGIN
DELETE FROM my_gtt_session WHERE session_id = v_sid;
END;
/
-- 3. 視圖屏蔽 SESSION_ID (應用透明)
CREATE OR REPLACE VIEW v_my_gtt_session AS
SELECT id, data
FROM my_gtt_session
WHERE session_id = SYS_CONTEXT('USERENV','SID');
-- 4. 高級用戶可查全局數據 (權限控制)
GRANT SELECT ON my_gtt_session TO admin_role;
優勢總結
- 支持 LOB、主外鍵、持久統計、分區、壓縮等所有普通表特性。
- 視圖 + 觸發器實現會話隔離透明化,應用代碼無感知。
- 管理員可跨會話審計/清理,符合合規要求。
12c+ 新特性:私有臨時表 (PTT)
-- 僅存在於當前會話,提交/會話結束自動消失,支持 LOB/索引/統計
CREATE PRIVATE TEMPORARY TABLE ORA$PTT_MY_DATA (
id NUMBER PRIMARY KEY,
data CLOB
) ON COMMIT PRESERVE DEFINITION; -- 定義跨事務保留,數據按 ON COMMIT 策略
-- 使用
INSERT INTO ORA$PTT_MY_DATA VALUES (1, 'large text...');
-- 會話結束自動清理,無需觸發器
PTT 結合了 GTT 易用性與普通表完整功能,12c2/18c+ 首選方案。