排序、雜湊連接、群組聚合、索引建立、分析收集——所有「中間結果集」都會產生臨時資料。Oracle 採用 **三層架構** 處理:PGA 排序區 (記憶體) → 臨時表空間 (磁碟) → 臨時段 (邏輯單位)。本文系統解析三層交互機制、配置優化策略、監控視圖與實戰避坑指南。
[SQL 執行需排序/雜湊/群組]
│
▼
┌────────────────────────┐
│ PGA 排序區 │ ← 記憶體優先,速度最快 (ns/μs)
│ (SORT_AREA_SIZE / │
│ PGA_AGGREGATE_TARGET) │
└───────────┬────────────┘
│ 記憶體不足 (超過排序區大小)
▼
┌────────────────────────┐
│ 臨時表空間 │ ← 磁碟落盤,速度較慢 (ms)
│ (TEMPORARY TABLESPACE) │
└───────────┬────────────┘
│ 分配臨時段
▼
┌────────────────────────┐
│ 臨時段 │ ← 邏輯儲存單位,由區間組成
│ (TEMPORARY SEGMENT) │
└────────────────────────┘
| 參數 | 版本 | 角色 | 建議值 |
|---|---|---|---|
WORKAREA_SIZE_POLICY = AUTO | 9i+ | 啟用自動 PGA 管理 (預設) | AUTO |
PGA_AGGREGATE_TARGET | 9i+ | 實例級 PGA 總量目標 (自動管理時) | 物理記憶體 20-30% (扣除 SGA 後) |
PGA_AGGREGATE_LIMIT | 12c+ | 硬性上限,超過觸發錯誤/終止會話 | 2-4x TARGET,防止失控 |
SORT_AREA_SIZE | 9i 前 / 手動模式 | 單次排序區大小 (手動模式) | 不建議使用,改用自動管理 |
優化原則:監控 V$PGASTAT 中 cache hit percentage > 90%,若偏低 → 增加 TARGET 或優化 SQL (減少排序/雜湊)。
ALTER TABLESPACE temp ADD TEMPFILE ... 多檔案分散 I/O,平行分配臨時段。CREATE TEMPORARY TABLESPACE temp TEMPFILE ... EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1M; 減少空間碎片與分配爭用。ORA-01652。-- 建立專用臨時表空間供特定服務/租戶
CREATE TEMPORARY TABLESPACE temp_dw TEMPFILE '+DATA/temp_dw01.dbf' SIZE 50G
EXTENT MANAGEMENT LOCAL UNIFORM SIZE 10M;
-- 指派給使用者
ALTER USER dw_user TEMPORARY TABLESPACE temp_dw;
-- 或資料庫預設 (12c+ PDB 級)
ALTER DATABASE DEFAULT TEMPORARY TABLESPACE temp_dw;
效益:資源隔離、配額控制、故障域限縮、效能基線清晰。
-- 實例級臨時段使用率
SELECT tablespace_name, total_blocks, used_blocks, free_blocks,
ROUND(used_blocks * 100 / total_blocks, 2) AS pct_used
FROM v$sort_segment;
-- 會話級臨時段佔用 (誰在用、用多少)
SELECT s.username, s.sid, s.serial#, u.tablespace, u.contents,
u.blocks * t.block_size / 1024 / 1024 AS mb_used,
u.sql_id, u.sql_exec_id
FROM v$tempseg_usage u
JOIN v$session s ON u.session_addr = s.saddr
JOIN dba_tablespaces t ON u.tablespace = t.tablespace_name
ORDER BY mb_used DESC;
SELECT tablespace_name,
SUM(bytes) / 1024 / 1024 AS total_mb,
SUM(bytes - free_bytes) / 1024 / 1024 AS used_mb,
ROUND(SUM(bytes - free_bytes) * 100 / SUM(bytes), 2) AS pct_used
FROM v$temp_space_header
GROUP BY tablespace_name;
SELECT snap_id, begin_interval_time,
temp_space_allocated / 1024 / 1024 AS alloc_mb,
temp_space_freed / 1024 / 1024 AS freed_mb
FROM dba_hist_tbspc_space_usage
WHERE tablespace_name = 'TEMP'
ORDER BY snap_id;
| 現象 | 根因 | 解決方案 |
|---|---|---|
| ORA-01652: unable to extend temp segment | 臨時表空間滿 | 1) ADD TEMPFILE 2) 增加 PGA 減少落盤 3) 優化 SQL (避免笛卡兒積、大排序) 4) 檢查長時間交易佔用 |
| 查詢緩慢、等待 "direct path write temp" | 大量排序/雜湊落盤 | 增加 PGA、建立適當索引避免排序、使用近似聚合 (APPROX_COUNT_DISTINCT) |
| 臨時表空間碎片化、分配緩慢 | 非統一區間、頻繁擴展 | 重建為 LOCAL UNIFORM SIZE、預先分配足夠空間 |
| 多租戶互相影響 | 共用單一 TEMP | 建立專用臨時表空間指派給 PDB/使用者 |
WORKAREA_SIZE_POLICY=AUTO + 合理 PGA_AGGREGATE_TARGET。UNIFORM SIZE 1M-10M 視資料量而定,減少位圖管理開銷。V$SORT_SEGMENT 使用率、V$TEMPSEG_USAGE Top Sessions、ORA-01652 告警。臨時表空間不是「臨時工」,而是高併發 OLTP 與大數據倉庫的**效能核心基礎設施**。掌握 **PGA → 臨時表空間 → 臨時段** 三層流轉機制,以「記憶體優先、磁碟兜底、隔離治理」為原則配置與監控,才能在排序、雜湊、聚合等核心運算中穩住效能底線。