適用場景
- 多大表關聯查詢,中間結果集極小且頻繁重用。
- 批次程式暫存中間計算結果,流程結束自動清理。
- 避免建立永久表造成 DDL 鎖、統計資訊維護負擔。
兩種 GTT 型別
| 型別 | 語法 | 資料生命週期 | 跨 Session 可見性 |
| 會話級 | ON COMMIT PRESERVE ROWS | Session 結束 (離開/斷線) 時 TRUNCATE | 各 Session 只見自己的資料,互不干擾 |
| 交易級 | ON COMMIT DELETE ROWS | COMMIT 或 ROLLBACK 時 TRUNCATE (Session 結束也清除) | 同左 |
建立範例
CREATE GLOBAL TEMPORARY TABLE student_temp (
stu_id NUMBER(5),
class_id NUMBER(5),
stu_name VARCHAR2(8),
stu_memo VARCHAR2(200)
) ON COMMIT PRESERVE ROWS;
CREATE GLOBAL TEMPORARY TABLE class_temp (
class_id NUMBER(5),
class_name VARCHAR2(8),
class_memo VARCHAR2(200)
) ON COMMIT DELETE ROWS;
GTT 關鍵特性
- 不佔用永久表空間:資料寫入暫存表空間 (TEMP),Session 結束自動釋放。
- DDL 無鎖爭用:建立/刪除 GTT 定義不影響其他 Session。
- 統計資訊共用:
DBMS_STATS.GATHER_TABLE_STATS 收集的是字典統計,所有 Session 共用。12c+ 支援 SESSION 級私有統計。
- 可建立索引:索引同樣儲存於 TEMP 表空間,Session 專用。
四大限制與避坑
- 不支援 LOB 型別 (BLOB/CLOB/NCLOB/BFILE) — 設計考量 TEMP 空間管理。
- 不支援外鍵 (Referential Integrity) — 無法建立 FK 指向 GTT 或 GTT 指向 FK。
- 不支援分區。
- 並行 DML (PDML) 限制:12c 前不支援,12c+ 有條件支援。
替代方案:自訂「擴充暫存表」突破限制
設計模式
- 建立永久表,PK 包含
SESSION_ID NUMBER (呼叫 SYS_CONTEXT('USERENV','SID'))。
- 建立
LOGOFF 觸發器:DELETE FROM my_temp WHERE session_id = :old_sid;。
- 應用寫入時自動帶入
SESSION_ID (可用 Trigger 透明化)。
- 查詢時加
WHERE session_id = SYS_CONTEXT('USERENV','SID') (可建 View 封裝)。
優勢
- 支援 LOB、外鍵、分區、PDML 所有功能。
- 高權限用戶可跨 Session 查詢全域資料 (審計/除錯)。
- 索引/統計資訊可針對全表最佳化。
成本
- 佔用永久表空間,需定期清理 (觸發器保證)。
- 需管理序列/觸發器額外物件。
選型決策樹
需要 LOB / 外鍵 / 分區 / PDML?
├─ 是 → 自訂擴充暫存表 (永久表 + SESSION_ID + LOGOFF Trigger)
└─ 否 → 資料量大 / 高併發 / 需索引?
├─ 是 → GTT (會話級 PRESERVE / 交易級 DELETE) + 12c SESSION 統計
└─ 否 → PL/SQL 集合 (Associative Array / Nested Table) 記憶體處理最快