在線交易處理(OLTP)環境中,每秒可能執行成千上萬條 SQL 語句。在 DB2 V9.7 之前,每條動態 SQL 執行都需要經過完整的編譯過程——解析、語義檢查、優化、生成存取路徑。編譯極度消耗 CPU 資源,若大量相似但文本不同的 SQL(僅字面值不同)重複編譯,系統吞吐量將嚴重受限。
DB2 區分兩類 SQL:
DB2 以 SQL 文本為鍵值進行哈希匹配。哪怕只有一個字母大小寫差異,哈希值便不同,導致被視為不同語句,無法共享計劃。例如:
select firstnme, lastname from employee where empno='000020'
select firstnme, lastname from employee where empno='000070'
雖然兩者邏輯相同、執行計劃一致(皆走索引 PK_EMPLOYEE),DB2 仍會各自編譯一次,白白浪費 CPU 週期。
DB2 V9.7 引入 Statement Concentrator(語句集中器),在伺服器端將動態 SQL 中的字面值替換為參數標記(如 :L0),使「結構相同、字面值不同」的語句映射為同一內部表示,從而共用單一編譯計劃。
| 層級 | 配置方式 | 適用場景 |
|---|---|---|
| 資料庫級(全域) | db2 update db cfg for <db> using STMT_CONC LITERALS |
希望所有連接自動受益,簡單粗暴 |
| 連接級(細粒度) | 在 db2cli.ini 設定 StmtConcentrator=WITHLITERALS,或在 ODBC/JDBC 程式中設定 SQL_ATTR_STMT_CONCENTRATOR |
僅特定應用啟用;跨 DB2 產品線(LUW、z/OS 等)一致的唯一方式 |
最佳實踐:優先採用連接級啟用,因其控制力最精細,且為全產品線通用標準。
啟用後重新執行上述兩條 SQL,再用 db2 get snapshot for dynamic sql on sample 觀察:
select firstnme, lastname from employee where empno=:L0,編譯數 = 1,執行數 = 2,編譯耗時 218 ms。顯而易見,兩次邏輯查詢僅編譯一次,CPU 開銷大幅降低。
MON_GET_ACTIVITY_DETAILS 等介面會同時顯示「原始語句」與「修改後語句」。預設僅替換前 100,000 個字面值,餘下保持原樣,實務上足以覆蓋絕大多數 OLTP 工作負載。
語句集中器是 DB2 V9.7 為高併發 OLTP 量身打造的「編譯去重器」。正確啟用它,能以極低成本換取顯著的 CPU 節省與吞吐提升,是 DBA 與開發人員必須掌握的效能優化利器。