首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

DB2 索引優化實戰:四大識別未用索引方法、工具鏈與安全清理策略

     編輯:DB2 教學

前言:索引雙刃劍 —— 查詢加速器 vs 寫入剎車器

過多索引是生產環境性能隱形殺手:每次 UPDATE/INSERT/DELETE 需同步維護所有索引,RUNSTATS/REORG 耗時線性增長,備份體積膨脹。核心課題:精準識別「真未用」與「極少用」索引,並在業務風險可控前提下清理。本文系統介紹四大識別方法、工具實操與治理策略。

方法一:DB2 Design Advisor (db2advis) —— 基於負載的專家建議

核心價值

  • 分析 SQL 負載集 (文件/緩存),輸出:建議新增索引、被使用現有索引、未被使用現有索引
  • 考慮查詢頻率權重,給出成本收益量化估算

實操步驟

# 1. 建立樣本庫與 Explain 表 (一次性)
db2sampl
db2 -tf $HOME/sqllib/misc/EXPLAIN.DDL

# 2. 準備 SQL 負載檔 (queries.sql)
--#SET FREQUENCY 123
SELECT LASTNAME FROM EMPLOYEE WHERE EMPNO = '000010';
--#SET FREQUENCY 456
SELECT LASTNAME FROM EMPLOYEE WHERE WORKDEPT = 'A00';
...

# 3. 執行分析
db2advis -d sample -i queries.sql -m I -l -1 -t 0 -o db2advis_out.txt

# 參數:-m I (僅索引) -l -1 (無大小限制) -t 0 (無時間限制)

輸出解讀


-- UNUSED EXISTING INDEXES
-- ============================
-- DROP INDEX "FECHNER"."XDEPT3";
-- DROP INDEX "FECHNER"."XPROJ2";
-- ============================

⚠️ 關鍵警示:建議僅基於輸入負載集。生產環境可能存在未納入負載的關鍵查詢 (月結報表、年審腳本、應急手工查詢)。刪除前必須全量 SQL 審計。

替代模式:直接分析 SQL 緩存


db2advis -d sample -g -m I -l -1 -t 0 -o db2advis_cache.txt
# -g 從套件緩存抓取 SQL

需在不同時段多次執行覆蓋完整業務週期。

方法二:db2pd 實用程式 —— 實時運行時計數器 (V8+)

核心指標

  • Scans:索引被掃描次數 (啟動後累計)
  • IxOnlyScans:純索引掃描次數 (無需回表,含蓋索引)
  • 總訪問 = Scans + IxOnlyScans

全庫掃描


db2pd -db sample -tcbstats all -file db2pd_all.txt

單表精準定位


# 1. 獲取 TBSPACEID, TABLEID
db2 "SELECT TBSPACEID, TABLEID FROM SYSCAT.TABLES WHERE TABSCHEMA='FECHNER' AND TABNAME='DEPARTMENT'"
# 結果: 2, 5

# 2. 針對性收集
db2pd -db sample -tcbstats all tbspaceid=2 tableid=5 -file db2pd_dept.txt

輸出範例解析


TCB Index Stats:
IID=1  Scans=245  IxOnlyScans=0  → 總計 245
IID=2  Scans=678  IxOnlyScans=0  → 總計 678
IID=3  Scans=0    IxOnlyScans=0  → 總計 0  ← 疑似未用

索引 ID 反查名稱


db2 "SELECT INDSCHEMA, INDNAME FROM SYSCAT.INDEXES WHERE TABSCHEMA='FECHNER' AND TABNAME='DEPARTMENT' AND IID=3"
# 結果: FECHNER XDEPT3

局限性

  • 計數器隨實例重啟歸零
  • 僅反映「啟動至今」視窗,季度/年度業務可能未覆蓋
  • 需結合業務日曆選擇觀測窗口

方法三:DB2 Workload Manager (WLM) 事件監視器 —— 生產級全負載審計 (V9.5+)

授權提示:WLM 核心功能需付費,但擴展資料庫監控選項免費,含本文使用的事件監視器。

部署步驟


# 1. 建立 Explain 表 (同方法一)
# 2. 建立並啟用 WLM 事件監視器
db2 -tf $HOME/sqllib/misc/wlmevmon.ddl
# 建立 DB2ACTIVITIES, DB2STATISTICS, DB2THRESHOLDVIOLATIONS 表 (預設 USERSPACE1)

# 3. 手動啟動 (或待下次激活自動啟動)
db2 "SET EVENT MONITOR DB2ACTIVITIES STATE 1"
db2 "SET EVENT MONITOR DB2STATISTICS STATE 1"
db2 "SET EVENT MONITOR DB2THRESHOLDVIOLATIONS STATE 1"

# 4. 針對預設服務子類啟用活動收集
db2 "ALTER SERVICE CLASS SYSDEFAULTSUBCLASS UNDER SYSDEFAULTUSERCLASS COLLECT ACTIVITY DATA ON ALL DATABASE PARTITIONS WITH DETAILS"

# 5. 觀測窗口 (如工作日 9:00-17:00) 後停用
db2 "ALTER SERVICE CLASS SYSDEFAULTSUBCLASS UNDER SYSDEFAULTUSERCLASS COLLECT ACTIVITY DATA NONE"

Perl 報告生成 (樣本腳本)


cd $HOME/sqllib/samples/perl
perl wlmhist.pl sample userid password
perl wlmhistrep.pl sample userid password wlmhistrep.txt

報告輸出結構


INDEXES HIT REPORT:
TABLE      SCHEMA   INDEX        TOTAL_HITS
DEPARTMENT FECHNER  PK_DEPARTMENT 245
DEPARTMENT FECHNER  XDEPT2        678
EMPLOYEE   FECHNER  PK_EMPLOYEE   123
...

INDEXES NOT HIT REPORT:
TABLE      SCHEMA   INDEX   TYPE
DEPARTMENT FECHNER  XDEPT3  REG
PROJECT    FECHNER  XPROJ2  REG
...

優勢:基於實際執行計劃 (EXPLAIN),捕獲真實負載全貌,含頻率、成本上下文。

方法四:MON_GET_INDEX 表函數 —— SQL 原生查詢介面 (V9.7+)

核心查詢


SELECT 
  SUBSTR(SI.INDSCHEMA,1,30) AS INDSCHEMA,
  SUBSTR(SI.INDNAME,1,30)   AS INDNAME,
  MGI.INDEX_SCANS,
  MGI.INDEX_ONLY_SCANS
FROM TABLE(MON_GET_INDEX('FECHNER','DEPARTMENT',-2)) AS MGI
JOIN SYSCAT.INDEXES SI
  ON MGI.TABSCHEMA=SI.TABSCHEMA
 AND MGI.TABNAME=SI.TABNAME
 AND MGI.IID=SI.IID
ORDER BY MGI.INDEX_SCANS DESC;

參數:Schema, Table, Partition (-1 當前, -2 所有)。省略表名 = 全模式;全省略 = 全庫。

輸出範例


INDSCHEMA  INDNAME        INDEX_SCANS  INDEX_ONLY_SCANS
FECHNER    XDEPT2         678          0
FECHNER    PK_DEPARTMENT  245          0
FECHNER    XDEPT3         0            0   ← 未用

優勢:純 SQL 介面,易整合監控儀表板、自動化報表、無需外部工具/腳本。

四大方法對比與選型指南

維度db2advisdb2pdWLM 事件監視器MON_GET_INDEX
適用版本V8+V8+V9.5+ (免費監控組件)V9.7+
數據來源負載檔/緩存 SQL運行時計數器實際執行活動 (EXPLAIN)運行時計數器 (表函數)
負載覆蓋輸入負載決定啟動至今觀測窗口內全負載啟動至今/重置後
輸出豐富度含新增建議、成本估算基礎計數含頻率、成本、計劃上下文基礎計數 + 易查詢
部署複雜度低極低中 (需監視器、Perl、Explain)極低 (單一 SQL)
推薦場景專項調優專案、遷移評估快速巡檢、單表診斷生產環境全負載審計、合規日常監控儀表板、自動化

安全清理治理策略:從識別到執行的閉環

  1. 多方法交叉驗證:至少兩種方法 (如 db2pd + MON_GET_INDEX) 一致判定為未用
  2. 業務日曆覆蓋:觀測窗口必須包含月結、季結、年結、稽核等低頻高重要業務
  3. 依賴關係掃描:檢查外鍵、物化視圖、MQT、觸發器、應用硬編碼 Hint 是否隱性依賴
  4. 保留 DDL 回滾包:執行 db2look -d <db> -t <tab> -i <user> -w -o idx_rollback.sql 導出索引 DDL
  5. 分階段執行:非核心表先行 → 核心表維護窗口執行 → 驗證應用無報錯 → 監控效能指標 (UID 耗時、日誌量、備份大小)
  6. 文檔化歸檔:記錄索引名、表、判定依據、執行時間、驗證結果、負責人

結語:索引治理是持續工程,而非一次專案

建立 「負載畫像 → 定期審計 → 風險評估 → 受控清理 → 效果驗證」 的索引生命週期管理機制。將索引數量納入資料庫健康度 KPI (如 Index/Table Ratio、Unused Index %), 讓精簡成為常態,而非救火動作。

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