DB2 全域暫存表(Declared Global Temporary Table,DGTT)是會話級私有資料結構,資料隨會話結束自動清除,不佔用系統目錄空間,是複雜 ETL、中間結果暫存、程序化邏輯的利器。
核心特性速覽
| 特性 | 說明 |
| 建立指令 | DECLARE GLOBAL TEMPORARY TABLE |
| 儲存位置 | 使用者暫存表空間(USER TEMPORARY TABLESPACE) |
| Schema | 固定為 SESSION,不出現在 SYSCAT.TABLES |
| 隔離性 | 會話級私有,不同會話同名表互不干擾 |
| 生命週期 | 會話結束或 ROLLBACK 時自動卸除 |
| 提交行為 | 預設 ON COMMIT DELETE ROWS,可指定 PRESERVE ROWS |
| 日誌記錄 | 可指定 NOT LOGGED 減少日誌開銷 |
前置需求:建立使用者暫存表空間
資料庫建立時預設不建立使用者暫存表空間,必須先建立:
-- 檢查現有暫存表空間
db2 "select tbspname, tbspcontent from syscat.tablespaces where tbspcontent='T'"
-- 建立使用者暫存表空間(自動儲存管理)
db2 "create user temporary tablespace usrtmpspc managed by automatic storage"
-- 或 SMS 方式(指定容器路徑)
db2 "create user temporary tablespace usrtmpspc managed by system using ('/db2/tmp/usrtmpspc')"
完整建立語法與範例
DECLARE GLOBAL TEMPORARY TABLE SESSION.RESULTS
(
RECID VARCHAR(32), -- 識別碼
XXLY VARCHAR(100), -- 訊息來源
LXDH VARCHAR(32), -- 來源聯絡電話
FKRQ DATE -- 回饋時間
)
ON COMMIT PRESERVE ROWS -- 提交時保留資料
WITH REPLACE -- 同名表存在時取代
NOT LOGGED; -- 不記錄日誌,效能最佳
關鍵選項說明
ON COMMIT PRESERVE ROWS:交易提交後保留資料(預設刪除)
ON COMMIT DELETE ROWS:提交後清空資料,保留定義
WITH REPLACE:同會話中重複宣告同名表時自動取代
NOT LOGGED:大量資料載入時強烈建議,避免日誌爆增;代價是不可恢復(媒體故障時資料遺失)
LOGGED:完整日誌記錄,支援回滾與恢復
操作範例流程
-- 1. 宣告暫存表
DECLARE GLOBAL TEMPORARY TABLE SESSION.TMP_SALES
( REGION VARCHAR(20), AMT DECIMAL(12,2) )
ON COMMIT PRESERVE ROWS NOT LOGGED;
-- 2. 插入中間運算結果
INSERT INTO SESSION.TMP_SALES
SELECT region, SUM(amount) FROM sales_fact
WHERE sale_date >= '2024-01-01'
GROUP BY region;
-- 3. 後續複雜分析查詢(多次引用暫存結果)
SELECT region, amt, amt / SUM(amt) OVER() AS pct
FROM SESSION.TMP_SALES
ORDER BY amt DESC;
-- 4. 會話結束自動清理,或手動卸除
-- DROP TABLE SESSION.TMP_SALES; -- 可選,會話結束隱式執行
與其他暫存機制比較
| 機制 | 可見範圍 | 持久化 | 目錄登錄 | 適用場景 |
DGTT (DECLARE GLOBAL TEMPORARY TABLE) | 單一會話 | 會話結束消失 | 否 | ETL 中間結果、複雜報表、程序私有資料 |
CGTT (CREATE GLOBAL TEMPORARY TABLE) | 所有會話共享定義,資料隔離 | 定義永久,資料會話級 | 是 (SYSCAT.TABLES) | 應用程式共用邏輯、固定結構暫存 |
| 實體表 + 定期清除 | 全域可見 | 永久 | 是 | 需跨會話共享、稽核追蹤、大量資料 |
效能優化建議
- 大量載入用
NOT LOGGED:減少 80%+ 日誌 I/O
- 建立索引:
CREATE INDEX ON SESSION.TMP_T (COL1) 支援暫存表索引
- RUNSTATS:大量資料後執行
RUNSTATS ON TABLE SESSION.TMP_T 更新統計
- 避免頻繁宣告/卸除:連線池環境中重複宣告有編譯開銷,考慮 CGTT 或實體表
- 監控表空間使用:
db2pd -db -tablespaces 觀察暫存表空間水位
常見錯誤與解決
| 錯誤 | 原因 | 解決 |
| SQL1584N | 缺少使用者暫存表空間 | 建立 USER TEMPORARY TABLESPACE |
| SQL0204N | 引用未加 SESSION. 前綴 | 必須使用 SESSION.TABLE_NAME 或設定 CURRENT PATH |
| SQL0911N | 暫存表空間滿 | 擴充表空間容器或增加 NOT LOGGED 減少日誌爭用 |