首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 依使用者重建索引自動化腳本:產生、分析碎片、排程執行全流程

     編輯:Oracle 資料庫相關知識

為何需要重建索引?

  • 大量 DML (DELETE/UPDATE) 導致 **索引碎片**:葉子塊稀疏、高度增加、Clustering Factor 惡化。
  • 重建效果:**釋放已刪除項目空間、降低樹高、重排 Clustering Factor、回收表空間**。
  • 表重組需 ALTER TABLE MOVE / SHRINK SPACE / EXPORT/IMPORT,索引重建獨立進行。

第一階段:產生重建腳本 (按 Owner)


SET ECHO OFF FEEDBACK OFF VERIFY OFF PAGESIZE 0 TERMOUT ON HEADING OFF
ACCEPT owner CHAR PROMPT 'Enter index owner: '

SPOOL rebuild_&owner..sql

SELECT 'REM +-----------------------------------------------+' || CHR(10) ||
       'REM | INDEX NAME : ' || owner || '.' || segment_name ||
       LPAD('|', 33 - (LENGTH(owner) + LENGTH(segment_name))) || CHR(10) ||
       'REM | BYTES      : ' || bytes ||
       LPAD('|', 34 - LENGTH(bytes)) || CHR(10) ||
       'REM | EXTENTS    : ' || extents ||
       LPAD('|', 34 - LENGTH(extents)) || CHR(10) ||
       'REM +-----------------------------------------------+' || CHR(10) ||
       'ALTER INDEX ' || owner || '.' || segment_name || CHR(10) ||
       'REBUILD' || CHR(10) ||
       'TABLESPACE ' || tablespace_name || CHR(10) ||
       'STORAGE (' || CHR(10) ||
       '  INITIAL '     || initial_extent  || CHR(10) ||
       '  NEXT '        || next_extent     || CHR(10) ||
       '  MINEXTENTS '  || min_extents     || CHR(10) ||
       '  MAXEXTENTS '  || max_extents     || CHR(10) ||
       '  PCTINCREASE ' || pct_increase    || CHR(10) ||
       ');' || CHR(10) || CHR(10)
FROM   dba_segments
WHERE  segment_type = 'INDEX'
AND    owner = UPPER('&owner')
ORDER  BY owner, bytes DESC;

SPOOL OFF
Windows 環境修改 SPOOL 路徑:SPOOL C:\oracle\rebuild_&owner..sql。
僅重建大索引:加條件 AND bytes > &max_bytes。

第二階段:碎片分析 — 判斷是否真需重建


-- 1. 驗證結構 (鎖表,較久)
ANALYZE INDEX &index_name VALIDATE STRUCTURE;

-- 2. 查詢碎片指標
COLUMN name FORMAT A30
COLUMN del_lf_rows HEADING 'Deleted|Leaf Rows' FORMAT 999,999,999
COLUMN lf_rows_used HEADING 'Used|Leaf Rows' FORMAT 999,999,999
COLUMN pct_deleted HEADING '% Deleted|Leaf Rows' FORMAT 999.99999

SELECT name,
       del_lf_rows,
       lf_rows - del_lf_rows AS lf_rows_used,
       TO_CHAR(del_lf_rows / lf_rows * 100, '999.99999') AS pct_deleted
FROM   index_stats
WHERE  name = UPPER('&index_name');

重建判準

  • 刪除比率 > 15~20% → **必須重建**。
  • 高度 (HEIGHT) > 3** 且刪除比率 > 10% → 考慮重建。
  • Clustering Factor 接近表行數** → 重建可改善 (但不保證)。
  • **LMT + ASSM 環境下**,碎片影響較小,**優先檢查統計資訊是否最新**。

第三階段:修改腳本參數 (可選)

  • PCTINCREASE 歸零:避免 Extent 指數增長碎片化 — PCTINCREASE 0。
  • 移至專用表空間:TABLESPACE idx_rebuild_ts 隔離熱點。
  • ONLINE 重建 (11g+)**:ALTER INDEX ... REBUILD ONLINE; **不鎖表**,DML 可並發,**生產首選**。
  • PARALLEL 加速**:ALTER INDEX ... REBUILD ONLINE PARALLEL 4; 大索引顯著縮短時間。

第四階段:排程執行與異常處理


-- 建立 Scheduler Job (每月第一天凌晨 02:00)
BEGIN
    DBMS_SCHEDULER.CREATE_JOB (
        job_name        => 'JOB_REBUILD_INDEXES_APP_OWNER',
        job_type        => 'SCRIPT',
        job_action      => '@/u01/scripts/rebuild_APP_OWNER.sql',  -- 外部腳本檔
        start_date      => TRUNC(SYSDATE) + 2/24,  -- 凌晨 02:00
        repeat_interval => 'FREQ=MONTHLY; BYMONTHDAY=1; BYHOUR=2; BYMINUTE=0; BYSECOND=0',
        enabled         => TRUE,
        comments        => 'Monthly index rebuild for APP_OWNER, skip on ORA-00054'
    );
END;
/

ORA-00054 (資源忙碌) 處理策略

  1. 腳本加入 WHENEVER SQLERROR CONTINUE 忽略單條失敗。
  2. Job 失敗不警報,**下次排程自動重試**。
  3. **極熱表 (核心交易表) 索引移出自動腳本**,改用 **Online Redefinition** 或 **維護窗口手動重建**。

進階:12c+ 自動索引維護 (Automatic Indexing)


-- 19c 自動索引功能 (需 Enterprise Edition + Tuning Pack)
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_MODE', 'IMPLEMENT');  -- 自動建立/重建/刪除
SELECT * FROM DBA_AUTO_INDEX_CONFIG;
SELECT * FROM DBA_AUTO_INDEX_EXECUTIONS ORDER BY EXECUTION_START DESC;
**注意**:自動索引**不包含手動重建現有索引**,互補關係。建議:**自動索引開啟 + 手動重建腳本針對大型/核心索引**。

結語

索引重建自動化三部曲:**產生腳本 → 碎片驗證 → 排程執行 + 異常忽略**。核心指標 **刪除葉子行比率 > 20%**,重建採用 **ONLINE PARALLEL**。熱表索引移出自動化,納入維護窗口人工處理。19c+ 開啟 Automatic Indexing 讓 Oracle 協助管理索引生命週期,DBA 專注於核心索引品質把關。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved