DB2 9 引入 pureXML 支持,讓 XML 數據以原生層次格式存儲與查詢。DB2 提供 SQL/XML 與 XQuery 兩種查詢語言,並擁有成熟的 XML 索引與 Schema 驗證機制。雖然傳統 DB2 性能準則同樣適用,但 XML 特有的特性仍需針對性優化。本文匯總 15 條 XML 性能黃金法則,助您構建高性能 XML 應用。
DB2 自治存儲與自調優記憶體管理已能滿足大多數場景。但對高性能要求的 XML 應用,針對性優化可帶來顯著提升。實踐證明,性能瓶頸通常僅需應用 1-2 條相關建議即可破解。
文檔粒度直接影響索引效率與解析性能。以部門-員工模型為例:
核心建議:DB2 利用索引過濾文檔,粒度越細,索引效益越大;DOM 解析器處理小文檔亦更高效。若難以抉择,傾向細粒度更稳妥。屬性與元素選擇本質是建模決策,元素更靈活(可重複、嵌套、擴展),屬性則有存儲優化紅利,但不應成為建模決策主導因素。
DMS (Database Managed Space) 表空間性能優於 SMS,對 XML 讀寫尤為明顯。DB2 9 默認創建 DMS,建議搭配自治存儲。大文檔會被分割為多個區域存儲於多頁面,頁面越大,分割越少,插入與全文檢索性能越好。
經驗法則:頁面大小 ≥ 2×平均文檔大小,且 ≤ 32KB。純 XML 場景首選 32KB;混合關係數據場景 16KB 或 8KB 更均衡。
若 XML 需大頁面而關係數據需小頁面,可使用 LONG IN 子句將 XML 列導向不同頁面大小的表空間:
CREATE BUFFERPOOL bp4k PAGESIZE 4K;
CREATE BUFFERPOOL bp32k PAGESIZE 32K;
CREATE TABLESPACE relData PAGESIZE 4K MANAGED BY AUTOMATIC STORAGE BUFFERPOOL bp4k;
CREATE TABLESPACE XMLData PAGESIZE 32K MANAGED BY AUTOMATIC STORAGE BUFFERPOOL bp32k;
CREATE TABLE product(pid BIGINT, name VARCHAR(20), description XML) IN relData LONG IN XMLData;
原則:除非確有性能收益,否則避免引入多種頁面大小,保持物理設計簡潔。
INSERT 與 IMPORT 底層機制相似,優化關鍵點:
ALTER TABLE ... APPEND ON 追加模式LOGBUFSZ、LOGFILSIZ,日誌置於快速 I/O 設備ACTIVATE NOT LOGGED INITIALLY 避免日誌COMMITCOUNT 設 ≥ 100 或省略讓 DB2 自動決定ALLOW WRITE ACCESS 避免鎖表-o cio)DB2 9 為 XML 數據引入 XDA (XML Data Area) 存儲對象,快照監視器新增獨立計數器:
Buffer pool xda logical reads = 2533633
Buffer pool xda physical reads = 189056
Asynchronous pool xda page reads = 97728
...
XDA 計數器解讀邏輯與關係對應計數器一致,可獨立分析 XML 緩衝池命中率、I/O 与臨時空間使用。
驗證會在解析階段增加 CPU 消耗(中等複雜度 Schema 可增 50%+),降低插入吞吐。決策邏輯:若應用層已驗證,DB2 層可跳過;若數據來源不可信,必須在 DB2 驗證以保障類型註解持久化(查詢時會強制類型檢查)。
/customerinfo/phone 優於 //phone,前者直接導航,後者需全文檢索。通配符 * 和 // 除性能損耗外,還可能返回非預期結果(如同時匹配客戶與助手電話)。
//name 會為客戶與助手姓名都建索引,膨脹索引體積並增加寫入維護成本。精準定義 /customerinfo/name 仅為目標元素建索引。極端反例://text() 為所有葉子節點建索引,寫入性能災難,僅適用於極少寫入、查詢不可預測的場景。
XMLQUERY 不會過濾行,返回空序列導致結果集膨脹且無法利用索引。正確模式:SELECT XMLQUERY(...) FROM table WHERE XMLEXISTS(...),實現索引加速與行級過濾。
XMLEXISTS('$i/customerinfo/phone = "..."') 恒為真(布爾值非空序列)。必須寫為 XMLEXISTS('$i/customerinfo[phone = "..."]')。多條件同理:[cond1 and cond2] 而非 cond1 and cond2。
優化器依賴統計信息生成執行計劃。RUNSTATS 已擴展支持 XML 數據與索引。大表可用抽樣(TABLESAMPLE SYSTEM (10) 或 BERNOULLI (15))大幅縮短耗時,頁級抽樣減 I/O,行級抽樣精度更高。
視圖定義保留關係列(如 unitID),查詢時直接對關係列加謂詞 WHERE unitID = 'WWPR',避免先構造全量 XML 再過濾,大型數據集性能差異數量級。
視圖包含 XML 列 info,查詢用 WHERE XMLEXISTS('$i/customerinfo[addr/pcode="95141"]' PASSING info) 而非對 XMLTABLE 生成的關係列 Zip 過濾,前者可利用 XML 索引預先過濾行。
預編譯一次,執行時傳參數值,避免重複編譯優化開銷。SQL/XML 函數 (XMLQUERY, XMLTABLE, XMLEXISTS) 支持將 SQL 參數傳入 XQuery:XMLEXISTS('$i/customerinfo[phone = $p]' PASSING info, CAST(? AS VARCHAR(12)) AS "p")。
優先使用二進制類型交換 XML:CLI 用 SQL_C_BINARY,Java 用 setBinaryStream/getBinaryStream。檢索大文檔用 BLOB 定位符 + XMLSERIALIZE(info AS BLOB(1M)),避免字符類型序列化觸發編碼轉換。
性能調優從自治特性起步,再按圖索驥應用 15 條建議。修復現有瓶頸需先用 Visual Explain、db2exfmt、快照監視器定位根因,而非盲目嘗試。XML 與關係數據同樣遵循「測量、分析、優化」科學方法論。