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

DB2 效能調校:善用約束條件讓優化器產生更優執行計畫

     編輯:DB2 教學

核心觀念:約束不只是資料完整性的守門員

定義 PRIMARY KEY、UNIQUE、FOREIGN KEY、CHECK 等強制約束時,DB2 會將其語義資訊登錄在系統目錄中。查詢優化器讀取這些中繼資料,能夠進行多種查詢重寫與優化:

  • 連結消除 (Join Elimination):若 FK 保證子表每列皆有對應父表行,且查詢未選取父表欄位,優化器直接移除 JOIN。
  • 聚合下推與簡化:唯一鍵保證分組鍵基數,優化器可省略 DISTINCT 或提前聚合。
  • FETCH FIRST N ROWS 優化:NOT NULL + 唯一索引可確保排序唯一性,優化器敢於使用更激進的存取路徑。

實戰範例:連結消除

情境:DAILY_SALES (銷售明細) 透過 CUST_KEY 參照 CUSTOMER (客戶主檔),已建立 FK 約束。

-- 原始查詢:需顯示產品描述,但不需客戶任何欄位
SELECT AMT_SOLD, SALE_PRICE, PROD_DESC
FROM DAILY_SALES DS
JOIN PRODUCT P ON DS.PROD_KEY = P.PRODKEY
JOIN CUSTOMER C ON DS.CUST_KEY = C.CUST_KEY;

優化器行為:偵測到 FK 保證 DS.CUST_KEY 必存在於 CUSTOMER,且 SELECT 清單無 C.*,直接將 CUSTOMER 從計畫中移除,等同:

SELECT AMT_SOLD, SALE_PRICE, PROD_DESC
FROM DAILY_SALES DS
JOIN PRODUCT P ON DS.PROD_KEY = P.PRODKEY;

效能提升:省去大表掃描/索引存取與連結運算,尤其當 CUSTOMER 極大時效果顯著。

資訊約束 (Informational Constraints) — 低負擔的替代方案

強制約束在大量 DML (INSERT/UPDATE/DELETE) 時需即時檢查,造成 CPU/鎖定開銷。若應用程式已在商業邏輯層保證資料正確性,可改用資訊約束:

ALTER TABLE DAILY_SALES
ADD CONSTRAINT FK_SALES_CUST FOREIGN KEY (CUST_KEY)
REFERENCES CUSTOMER (CUST_KEY)
NOT ENFORCED ENABLE QUERY OPTIMIZATION;
  • NOT ENFORCED:寫入時不檢查,零運行期開銷。
  • ENABLE QUERY OPTIMIZATION:優化器仍可使用其語義進行上述重寫。

風險提醒:若應用程式邏輯有缺陷導致髒資料寫入,查詢結果可能不正確 (如上例若存在孤兒 CUST_KEY,連結消除會漏掉該筆銷售資料)。務必在測試環境驗證應用層驗證完備後再啟用。

約束對載入效能的影響與對策

操作強制約束影響建議對策
LOAD INSERT逐筆檢查 FK/CHECK,極慢LOAD 前 SET INTEGRITY OFF;載入後 SET INTEGRITY IMMEDIATE CHECKED (批次驗證)
大量 UPDATE/DELETE觸發 FK 串聯檢查/動作分批次提交;評估暫時 DISABLE FK (謹慎)
資訊約束無運行期檢查大量載入首選,但需確保資料品質

DB2 約束優化示意圖

最佳實踐清單

  1. 核心業務表務必定義 PK/FK/UNIQUE/CHECK,啟用強制模式。
  2. 資料倉儲/星狀模式事實表:維度表 FK 改用 NOT ENFORCED ENABLE QUERY OPTIMIZATION,ETL 層負責資料品質。
  3. 定期執行 RUNSTATS 收集約束相關統計 (如 FK 參照基數)。
  4. 利用 db2look -d dbname -e -x 匯出 DDL 審視約束完整性。
  5. 變更約束狀態 (ENFORCED/NOT ENFORCED) 後務必 REBIND 相關套件。

將約束視為「優化器的提示註解」而非單純防呆機制,善用 ENABLE QUERY OPTIMIZATION,即能在資料完整性與查詢效能間取得最佳平衡。

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