Oracle 全域暫存表(Global Temporary Table,GTT)是處理會話級或交易級中間運算結果的利器。與傳統永久表不同,GTT 的**定義持久化、資料隔離、自動清理**三大特性,能大幅降低 Redo/Undo 開銷、簡化應用邏輯。本文系統梳理 GTT 的架構原理、兩種保留模式、建立語法、限制條件與最佳實踐。
| 特性 | 說明 |
|---|---|
| 定義持久化 | DDL 建立後長期存在於資料字典,跨會話可見,無需重複建立 |
| 資料隔離 | 各會話只能看見自己的資料,互不干擾 |
| 自動清理 | 依模式於 COMMIT 或離開會話時自動截斷,無額外開銷 |
| Redo 極少 | 僅產生 Undo 相關 Redo,大幅優於永久表 |
| 可建立索引/觸發器/視圖 | 支援大部分永久表物件特性 |
CREATE GLOBAL TEMPORARY TABLE temp_session (
empno NUMBER(4),
ename VARCHAR2(20)
) ON COMMIT PRESERVE ROWS;
DELETE/TRUNCATE 前持續存在。COMMIT 仍保留,適合多步驟交易流程共用中間結果。CREATE GLOBAL TEMPORARY TABLE temp_txn (
empno NUMBER(4),
ename VARCHAR2(20)
) ON COMMIT DELETE ROWS;
CREATE GLOBAL TEMPORARY TABLE gtt_sales_summary (
region_id NUMBER(3),
sales_amt NUMBER(15,2),
calc_date DATE DEFAULT SYSDATE
)
ON COMMIT PRESERVE ROWS -- 或 DELETE ROWS
-- 可選:指定暫存表空間
-- TABLESPACE temp_tbs
-- 可選:平行度
-- PARALLEL 4;
| 支援 | 不支援 |
|---|---|
| 索引(含複合、函數式) | 外鍵約束(FK) |
| 觸發器(DML/系統事件) | 巢狀表欄位(9i 前 VARRAY 也不支援,10g+ 已支援) |
| 檢查約束、非空約束 | 索引組織表(IOT) |
| 視圖引用 GTT | 叢集、分區 |
| 統計收集(DBMS_STATS,12c+) | ANALYZE 命令收集統計 |
錯誤做法:
SELECT ... INTO #temp FROM ...動態建表(執行期 DDL)正確做法:
- 部署階段 一次性建立 GTT(如同永久表)
- 執行期僅
INSERT INTO gtt_temp SELECT ... FROM ...
避免執行期 DDL 帶來的硬解析、鎖爭用、計畫失效等效能殺手。
-- 會話級統計(僅對當前會話生效)
EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=>USER, tabname=>'GTT_SALES', scope=>'SESSION');
-- 或啟用動態採樣
ALTER SESSION SET OPTIMIZER_DYNAMIC_SAMPLING = 4;
ON COMMIT PRESERVE ROWS 表索引隨資料持久;DELETE ROWS 表索引隨資料清空自動維護。TEMP 表空間足夠並啟用 AUTOEXTEND。V$TEMPSEG_USAGE 觀察暫存段使用情況。-- 1. 會話級 GTT 保留跨步驟中間結果
CREATE GLOBAL TEMPORARY TABLE gtt_stage_cust ON COMMIT PRESERVE ROWS AS
SELECT * FROM staging_customers WHERE 1=0;
-- 2. 步驟 A:載入原始資料
INSERT INTO gtt_stage_cust SELECT * FROM ext_customers;
-- 3. 步驟 B:清洗轉換
UPDATE gtt_stage_cust SET ...;
-- 4. 步驟 C:寫入目標表
INSERT INTO dw_customers SELECT * FROM gtt_stage_cust;
-- 5. 會話結束自動清理,無需額外維護
DBMS_STATS 或動態採樣。善用全域暫存表,能讓複雜的多階段運算、報表暫存、ETL 中間層邏輯變得簡潔、高效且易維護,是 Oracle 開發者工具箱中的必備利器。