大型資料庫中 80% 空間常被 20% 表佔用。針對這些核心對象,從邏輯分區、索引維護、段碎片消除、自由區塊合併四個維度建立常態化優化機制,是支撐 TB/PB 級資料庫穩定高效運行的基石。本文提供標準化實施框架、關鍵 SQL、排程策略與效果驗證方法。
CREATE TABLE employee (
emp_no VARCHAR2(10) PRIMARY KEY,
name VARCHAR2(30),
dept_no NUMBER(2)
)
PARTITION BY RANGE (dept_no) (
PARTITION part1 VALUES LESS THAN (11) TABLESPACE part1_ts,
PARTITION part2 VALUES LESS THAN (21) TABLESPACE part2_ts,
PARTITION part3 VALUES LESS THAN (31) TABLESPACE part3_ts,
PARTITION part4 VALUES LESS THAN (MAXVALUE) TABLESPACE part4_ts
);
CREATE INDEX employee_dept_idx ON employee(dept_no) LOCAL (
PARTITION part1 TABLESPACE part1_idx_ts,
PARTITION part2 TABLESPACE part2_idx_ts,
PARTITION part3 TABLESPACE part3_idx_ts,
PARTITION part4 TABLESPACE part4_idx_ts
);
原則:
• 優先使用 LOCAL 索引:分區與索引分區 1:1 對應,支援分區級維護 (TRUNCATE/EXCHANGE/MOVE 自動同步索引分區)
• GLOBAL 索引僅用於:跨分區唯一性約束 (PK/UK 不含分區鍵)、特定高頻點查需求
• 分區剪枝:查詢條件包含分區鍵 → 僅掃描相關分區,效能指數級提升
-- 增加分區
ALTER TABLE employee ADD PARTITION part5 VALUES LESS THAN (41) TABLESPACE part5_ts;
-- 截斷分區 (歸檔/清理歷史數據,秒級)
ALTER TABLE employee TRUNCATE PARTITION part1;
-- 交換分區 (數據載入/歸檔,零數據移動)
ALTER TABLE employee EXCHANGE PARTITION part1 WITH TABLE emp_staging;
-- 移動分區 (跨表空間/壓縮/重建)
ALTER TABLE employee MOVE PARTITION part2 TABLESPACE new_ts COMPRESS FOR OLTP;
-- 合併/分裂分區
ALTER TABLE employee MERGE PARTITIONS part3, part4 INTO PARTITION p34;
ALTER TABLE employee SPLIT PARTITION p34 AT (35) INTO (PARTITION part3, PARTITION part4);
頻繁 DELETE/UPDATE 導致索引葉塊大量「已刪除標記」條目。這些空間不自動回收,只能被相同鍵值復用。結果:索引膨脹、樹高增加、快速全掃描/範圍掃描變慢、緩存命中率下降。
-- 單索引重建 (ONLINE 避免鎖表,12c+ 支援)
ALTER INDEX employee_dept_idx REBUILD ONLINE;
-- 分區索引重建 (逐分區,減少鎖衝突)
ALTER INDEX employee_dept_idx REBUILD PARTITION part1 ONLINE;
-- 批次重建腳本 (每日低峰執行)
BEGIN
FOR idx IN (SELECT index_name, owner FROM dba_indexes
WHERE owner = 'APP_SCHEMA'
AND index_type != 'LOB'
AND status = 'VALID') LOOP
BEGIN
EXECUTE IMMEDIATE 'ALTER INDEX ' || idx.owner || '.' || idx.index_name || ' REBUILD ONLINE';
DBMS_OUTPUT.PUT_LINE('Rebuilt: ' || idx.index_name);
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Failed: ' || idx.index_name || ' - ' || SQLERRM);
END;
END LOOP;
END;
/
-- 配合 ANALYZE INDEX ... VALIDATE STRUCTURE 獲取 HEIGHT、LF_BLKS、DEL_LF_ROWS 判斷是否需重建
HEIGHT > 3 (或 > 4 視資料量) → 考慮重建DEL_LF_ROWS / LF_ROWS > 20% → 碎片嚴重LF_BLKS 顯著大於理論值 → 空間浪費段由多個不連續區組成。區不連續 → 讀取需多次磁頭移動/搜尋 → I/O 效能下降。區數達上限 (MAXEXTENTS) → 無法擴展 → ORA-01631/01632。
SELECT owner, segment_name, segment_type, extents, bytes/1024/1024 size_mb
FROM dba_segments
WHERE extents > 100 -- 經驗閾值
ORDER BY extents DESC;
| 方案 | 操作 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|---|
| CTAS 重建 | CREATE TABLE new_t TABLESPACE new_ts AS SELECT * FROM old_t; DROP TABLE old_t; RENAME new_t TO old_t; | • 徹底消除碎片,段變單區 • 可同時調整存儲參數、表空間、壓縮 • 速度快 (直路徑載入) | • 需停機/鎖表 • 需雙倍空間 • 索引/約束/權限/觸發器需重建 | 維護窗口充裕、表可鎖定 |
| Export/Import | exp system/pwd file=exp.dmp compress=y grants=y indexes=y tables=(t1,t2) -- compress=y 導出時調整存儲參數 (INITIAL=總大小, NEXT=0) DROP TABLE t1, t2; imp system/pwd file=exp.dmp commit=y buffer=64000 full=y | • 跨平台/版本遷移同步解決 • 可重組存儲參數 • 不需目標端雙倍空間 (流式導入) | • 速度慢 (邏輯導出/導入) • 導入期間表不可用 • 需足夠導出檔空間 | 跨環境遷移、無維護窗口但可接受長時間不可用 |
零停機重建段,參考文章 94509。適用於 7×24 核心表。
PCTINCREASE > 0 由 SMON 定期合併)-- 合併指定表空間所有相鄰自由區塊
ALTER TABLESPACE users COALESCE;
-- 監控合併效果
SELECT tablespace_name,
COUNT(*) chunk_count,
ROUND(MAX(bytes)/1024/1024,2) max_chunk_mb,
ROUND(SUM(bytes)/1024/1024,2) total_free_mb
FROM dba_free_space
GROUP BY tablespace_name
ORDER BY max_chunk_mb;
CHUNK_COUNT > 1000 或 MAX_CHUNK_MB < 100 → 告警| 頻率 | 作業 | 關鍵動作 | 產出 |
|---|---|---|---|
| 每日 | 空間/碎片巡檢 | 表空間使用率、最大自由區塊、段區數 Top 20 | 每日空間報告 |
| 每周 | 索引健康掃描 | ANALYZE INDEX VALIDATE STRUCTURE 抽樣、HEIGHT/DEL_LF_ROWS 統計 | 待重建索引清單 |
| 每月 | 分區管理 | 新增/截斷/歸檔分區、分區剪枝效果驗證 | 分區調整記錄 |
| 每月 | 段碎片整理 | CTAS/線上重定義重建高碎片段 (extents > 100) | 重建報告、空間回收量 |
| 每月 | 自由區塊合併 | ALTER TABLESPACE ... COALESCE 高碎片表空間 | 合併前後對比圖 |
| 每季 | 架構審視 | 大表分區策略評估、索引覆蓋率分析、壓縮率優化 | 優化提案文檔 |
分區治理大表邏輯、索引重建恢復存取路徑、段重建消除物理碎片、自由區塊合併保障空間分配 — 四大支柱缺一不可。將其納入常態化排程、標準化腳本、指標化監控、文檔化複盤,即可構建「自我優化」的資料庫生態。請從本月開始,為你的核心表空間建立「碎片健康檔案」,讓每一次優化都有據可依、有效可驗。