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

DB2 V9.7 Statement Concentrator (語句集中器) 實戰:減少動態 SQL 編譯開銷

     編輯:DB2 教學

背景:動態 SQL 編譯風暴

  • 靜態 SQL:BIND 時確定執行計劃,執行僅調取。
  • 動態 SQL:每次執行編譯,計劃不在包緩存則重新編譯。
  • OLTP 環境秒級執行成千動態 SQL,編譯 CPU 開銷巨大。
  • DB2 用 HASH 演算法比對 SQL 文本,大小寫、字面值不同即視為不同語句,即使執行計劃相同 (如 WHERE empno='000020' vs '000070'),仍各自編譯。

語句集中器原理與啟用

DB2 V9.7 推出:修改動態 SQL 文本,使相似語句共享同一執行計劃。字面值被參數標記 (如 :L0) 取代。

兩種啟用層級

  1. 資料庫級 (全局):db2 update db cfg for sample using STMT_CONC LITERALS (預設 OFF)。前 100,000 個字面值替換,其餘保持。
  2. 連接級 (客戶端):db2cli.ini 設 StmtConcentrator=WITHLITERALS (OFF 關閉)。影響 SQL_ATTR_STMT_CONCENTRATOR 屬性,ODBC/JDBC 程式可直接設連接屬性。建議優先用客戶端級:控制粒度更細、全 DB2 產品線一致方式。

啟用後,原始語句與修改後語句均顯示於 Explain 輸出;事件監視器、MON_GET_ACTIVITY_DETAILS 顯示原始語句,其他監視介面顯示修改後文本。

實測驗證:編譯次數從 2 降為 1

-- 啟用 STMT_CONC LITERALS
SELECT firstnme,lastname FROM employee WHERE empno='000020';
SELECT firstnme,lastname FROM employee WHERE empno='000070';

-- get snapshot for dynamic sql
-- 結果:兩原始 SQL 編譯/執行數為 0;參數化語句 'empno=:L0' 編譯 1 次、執行 2 次、編譯時間 218ms

限制與風險:執行計劃可能變差

語句集中改變文本,影響執行計劃選擇。適用:包緩存中相似語句大量重複執行。不適用:不同字面值導致計劃顯著不同 (如數據嚴重傾斜)。

反面教材:數據傾斜導致計劃錯誤

  • 測試表 10 萬行:Col1 遞增,Col2 值 5 佔 90,001 行,其他值均勻分布 10,000 範圍內,Col2 有索引。
  • STMT_CONC OFF:
    • Col2=1:索引掃描 + RID 回表,成本 15.16,回 1.57 行
    • Col2=5:全表掃描,成本 953.76,回 90,001 行
  • STMT_CONC LITERALS:兩者共用同一計劃 (索引掃描 + RID 回表),成本 20.46,估計回 15.75 行。
    • Col2=1 時結果集被高估;Col2=5 時嚴重低估 (90,001 → 15.75),導致選錯計劃 (應全表掃描卻走索引)。
  • 執行時間對比:
    STMT_CONC=OFFSTMT_CONC=LITERALS
    Col2=10.607 秒0.732 秒
    Col2=517.73 秒21.65 秒

    Col2=5 時因計劃錯誤多花 ~3 秒。

結語與建議

  • 資料庫級用 STMT_CONC 參數;精確控制用客戶端 StmtConcentrator。
  • 適合大量小 SQL 的 OLTP 環境減少編譯開銷。
  • OLAP 或字面值導致計劃顯著不同場景慎用,必須測試驗證計劃穩定性。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved