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

DB2 MQT 物化查詢表深度實戰:從建立到查詢重寫的完整優化指南

     編輯:DB2 教學

前言

Materialized Query Table (MQT) 是 DB2 查詢優化的核心武器:預先計算並儲存複雜查詢結果,優化器自動重寫 SQL 導向 MQT,實現數量級效能提升。本文詳細解析 MQT 類型、建立語法、維護策略、查詢重寫機制與實戰優化案例。

一、MQT 核心概念與分類

類型定義特徵維護方式適用場景
系統維護 MQT (REFRESH IMMEDIATE)基於查詢定義,含 GROUP BY基礎表變更時自動同步更新高頻讀取、低頻寫入、需強一致性
系統維護 MQT (REFRESH DEFERRED)基於查詢定義手動/排程 REFRESH TABLE資料倉庫、彙總報表、可容忍延遲
用戶維護 MQT由應用程式負責填充數據應用程式 INSERT/UPDATE/DELETE複雜邏輯無法用 SQL 表達、跨系統彙總
階段表 (Staging Table)記錄基礎表變更的輔助表自動/手動維護支援 REFRESH DEFERRED MQT 的增量刷新

關鍵區別: MQT = 物化視圖 (Materialized View)。視圖每次查詢重新計算,MQT 儲存實體數據。

二、REFRESH IMMEDIATE MQT 完整建立範例


-- 1. 連線範例資料庫
CONNECT TO SAMPLE;

-- 2. 前置條件:REFRESH IMMEDIATE 要求每個引用表有唯一鍵出現在 SELECT 列表
ALTER TABLE EMPLOYEE ADD UNIQUE (EMPNO);
ALTER TABLE DEPARTMENT ADD UNIQUE (DEPTNO);

-- 3. 建立 MQT:員工部門彙總視圖
CREATE TABLE EMP_DEPT_MQT AS (
    SELECT 
        E.EMPNO,
        E.FIRSTNME,
        E.LASTNAME,
        E.PHONENO,
        D.DEPTNO,
        SUBSTR(D.DEPTNAME, 1, 12) AS DEPARTMENT,
        D.MGRNO
    FROM EMPLOYEE E
    INNER JOIN DEPARTMENT D ON E.WORKDEPT = D.DEPTNO
)
DATA INITIALLY DEFERRED          -- 建立時不填充數據
REFRESH IMMEDIATE                -- 基礎表變更自動同步
;

-- 4. 初始化數據並驗證完整性
SET INTEGRITY FOR EMP_DEPT_MQT IMMEDIATE CHECKED NOT INCREMENTAL;

語法關鍵字解析:

  • DATA INITIALLY DEFERRED:建立元數據不填數據,進入「檢查暫掛」狀態
  • REFRESH IMMEDIATE:承諾基礎表變更時自動維護 (觸發器機制)
  • SET INTEGRITY ... IMMEDIATE CHECKED NOT INCREMENTAL:全量檢查並填充初始數據
  • NOT INCREMENTAL:對整表檢查 (而非增量),初始化必用

三、REFRESH DEFERRED MQT 與增量刷新


-- 建立延遲刷新 MQT:月度銷售彙總
CREATE TABLE MONTHLY_SALES_MQT AS (
    SELECT 
        YEAR(SALES_DATE) AS SALES_YEAR,
        MONTH(SALES_DATE) AS SALES_MONTH,
        PRODUCT_ID,
        SUM(QUANTITY) AS TOTAL_QTY,
        SUM(AMOUNT) AS TOTAL_AMT,
        COUNT(*) AS TRANS_CNT
    FROM SALES_FACT
    GROUP BY YEAR(SALES_DATE), MONTH(SALES_DATE), PRODUCT_ID
)
DATA INITIALLY DEFERRED
REFRESH DEFERRED
;

-- 初始化
SET INTEGRITY FOR MONTHLY_SALES_MQT IMMEDIATE CHECKED NOT INCREMENTAL;

-- 定期刷新 (排程作業)
REFRESH TABLE MONTHLY_SALES_MQT;

-- 增量刷新 (需建立階段表)
CREATE TABLE MONTHLY_SALES_STG FOR MONTHLY_SALES_MQT PROPAGATE IMMEDIATE;
-- 基礎表變更自動記錄到階段表
REFRESH TABLE MONTHLY_SALES_MQT INCREMENTAL;  -- 僅處理階段表變更

四、查詢重寫機制與驗證

1. 優化器自動重寫條件

  • 查詢語義與 MQT 定義完全匹配或可推導
  • MQT 數據足夠新鮮 (IMMEDIATE 總是新鮮,DEFERRED 需檢查)
  • 成本估算:走 MQT 比走基礎表成本更低
  • 資料庫配置:QUERY_HEURISTICS、CURRENT REFRESH AGE 允許使用延遲數據

2. 驗證重寫是否生效


-- 方法 1:EXPLAIN 計劃查看
EXPLAIN PLAN FOR
SELECT DEPTNO, COUNT(*) FROM EMPLOYEE JOIN DEPARTMENT ... GROUP BY DEPTNO;

db2exfmt -d SAMPLE -1 -o plan.txt
# 檢查輸出中是否出現 EMP_DEPT_MQT 表存取

-- 方法 2:當前查詢優化層級
SET CURRENT QUERY OPTIMIZATION 5;  -- 預設 5,啟用 MQT 重寫
SET CURRENT REFRESH AGE ANY;       -- 允許使用 DEFERRED MQT

五、實戰優化案例:銷售儀表板查詢加速

原始查詢 (執行 45 秒)


SELECT 
    YEAR(s.sales_date) AS yr,
    MONTH(s.sales_date) AS mon,
    p.category,
    SUM(s.amount) AS revenue,
    COUNT(DISTINCT s.customer_id) AS cust_cnt
FROM sales_fact s
JOIN product_dim p ON s.product_id = p.product_id
JOIN customer_dim c ON s.customer_id = c.customer_id
WHERE s.sales_date >= '2023-01-01'
GROUP BY YEAR(s.sales_date), MONTH(s.sales_date), p.category
ORDER BY yr, mon, revenue DESC;

MQT 設計


CREATE TABLE SALES_MONTHLY_CAT_MQT AS (
    SELECT 
        YEAR(sales_date) AS yr,
        MONTH(sales_date) AS mon,
        category,
        SUM(amount) AS revenue,
        COUNT(DISTINCT customer_id) AS cust_cnt
    FROM sales_fact s
    JOIN product_dim p ON s.product_id = p.product_id
    JOIN customer_dim c ON s.customer_id = c.customer_id
    GROUP BY YEAR(sales_date), MONTH(sales_date), category
)
DATA INITIALLY DEFERRED REFRESH DEFERRED;

優化後查詢 (執行 0.3 秒,150x 提升)


-- 應用程式 SQL 無需修改,優化器自動重寫導向 MQT
SELECT yr, mon, category, revenue, cust_cnt
FROM SALES_MONTHLY_CAT_MQT
WHERE yr >= 2023
ORDER BY yr, mon, revenue DESC;

六、MQT 設計最佳實踐

  1. 粒度匹配:MQT 分組粒度需覆蓋高頻查詢的 GROUP BY 組合
  2. 預計算昂貴運算:DISTINCT COUNT、複雜連接、窗口函數預先計算
  3. 索引配合:MQT 上建立符合查詢謂詞的索引 (如 yr, mon, category)
  4. 分區對齊:大表 MQT 採用相同分區鍵 (如按年分區)
  5. 刷新窗口:DEFERRED MQT 刷新排在 ETL 完成後、業務查詢高峰前
  6. 監控指標:REFRESH_TIME、CARDINALITY、QUERY_REWRITE_HIT_RATIO

七、限制與避坑指南

限制影響替代方案
REFRESH IMMEDIATE 不允許直接 DML無法手工修正數據改用 DEFERRED + 階段表增量刷新
基礎表結構變更需重建 MQTDDL 變更導致 MQT 失效變更管理流程納入 MQT 重建步驟
外部表/暫存表不可引用跨資料庫查詢無法建立 MQT用戶維護 MQT + ETL 填充
遞歸查詢、非確定性函數不可用限制 MQT 定義複雜度應用層預計算 + 用戶維護 MQT

結語

MQT 是 DB2 「以空間換時間、以預計算換即時計算」的經典實踐。系統維護 REFRESH DEFERRED + 階段表增量刷新是資料倉庫場景的黃金組合:平衡了查詢效能、維護成本與數據新鮮度。建立「MQT 設計 → 驗證重寫 → 監控刷新」閉環流程,讓 MQT 持續產出價值。

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