臨時表濫用的隱性代價
當業務邏輯難以用單條 SQL 表達時,開發傾向創建臨時表中轉。但在**高併發多用戶**系統中,頻繁 CREATE/DROP TEMP TABLE 會導致:
- 系統表鎖競爭:數據字典(
OBJ$, TAB$ 等)高頻修改產生行鎖/庫鎖。
- 空間碎片化:臨時段分配/釋放產生大量碎片,影響永久對象分配效率。
- 解析風暴:每次創建觸發硬解析,Library Cache 壓力劇增。
- UNDO/REDO 暴增:DDL 隱式提交 + 臨時段操作產生大量日志。
優化策略三板斧
1. 源頭減少:能不用就不用
- 優先改寫為 **CTE (WITH 子句)**、內聯視圖、分析函數、物化視圖 完成邏輯。
- 複雜報表採用 **物化視圖預計算** + 定時刷新,查詢時直接讀結果。
- ETL 中轉採用 **永久階段表 (Staging Table)** + 分區交換,避免 DDL。
2. 生命周期管控:共享與複用
- 全局臨時表 (GTT):
CREATE GLOBAL TEMPORARY TABLE ... ON COMMIT PRESERVE/DELETE ROWS。
定義一次,會話級/事務級數據隔離,**零 DDL 開銷**,統計信息可共享(DBMS_STATS.SET_TABLE_STATS)。
- 連接池綁定:應用連接池預熱時預建 GTT,會話複用期間反覆
TRUNCATE 而非 DROP/CREATE。
- TTL 機制:調度任務定期清理長閒置臨時段(
DBA_TEMP_FREE_SPACE 監控)。
3. 資源配額與監控:防止失控
- 表空間配額:為臨時表空間設置用戶級
TEMPORARY TABLESPACE QUOTA,防單用戶佔滿。
- 行/列上限:治理超寬/超長臨時表(如 >100 列或 >1000 萬行),強制拆分或轉正規表。
- 監控儀表盤:
- V$TEMPSEG_USAGE 實時臨時段佔用 Top 10 會話
- DBA_HIST_TEMP_STAT 歷史趨勢
- 告警:單會話臨時段 > 1GB 或 佔用 > 80% 表空間
最佳實踐清單
- 代碼審核強制:臨時表創建需架構師簽署,註明不可替代理由。
- 新項目默認 **GTT + 連接池預熱** 模式。
- 存量系統識別高頻臨時表(AWR
TEMP SPACE ALLOCATED Top SQL),重構為 GTT/CTE。
- 文檔化臨時表用途、預估行數、生命周期、清理策略。