DB2 支持路徑專用 XML 索引,僅對謂詞與連接高頻出現的元素/屬性建立索引。例如針對定期存款本金金額:
create index tdpa on trades(tradedoc) generate keys
using XMLpattern '/FpML/trade/termDeposit/principal/amount' as sql double;
索引鍵隨文檔增刪改自動維護。權衡點:索引佔用空間、維護開銷與查詢收益成正比,鍵值數量等於文檔中匹配 XPath 的節點數。
為外匯交易支付金額建立索引,若使用 //paymentAmount/amount 這類雙斜線通配符:
正解:精確指定路徑 /FpML/trade/fxSingleLeg/*/paymentAmount/amount,兼顧精準與通配靈活性。
DB2 提供 5 種 XML 索引類型:DOUBLE、VARCHAR(n)、VARCHAR HASHED、DATE、TIMESTAMP。類型不匹配索引失效:
"510026")被視為字符串,DOUBLE 索引無法使用 → 改用 VARCHAR 索引或去除引號"2002-02-14Z" 匹配 VARCHAR 而非 DATE 索引 → 查詢中轉型 xs:date("2002-02-14Z")字符串索引選型表:
| 索引類型 | 適用謂詞 | 長度限制 | 典型場景 |
|---|---|---|---|
| VARCHAR(n) | 範圍、等值、排序 | N 字節 | 短字符串、需範圍查詢 |
| VARCHAR HASHED | 僅等值 | 無限制 | 長字符串、純等值過濾 |
經驗法則:純等值查詢優先 VARCHAR HASHED,特別是長文本;需範圍/排序則用 VARCHAR(n)。
葉子元素值等同於其文本節點,謂詞加不加 /text() 結果相同,但索引定義必須與查詢完全一致:
currency = "EUR" → 索引定義 /FpML/.../currencycurrency/text() = "EUR" → 索引定義 /FpML/.../currency/text()非葉子節點(如 <principal> 包含 currency+amount)其值為所有後代文本串聯(EUR25000000.00),極少建議對非葉子節點建索引,除非極其確定結構穩定且查詢確需前綴匹配。
索引路徑必須包含查詢謂詞路徑的所有節點。查詢用通配符 FpML//currency 範圍超過索引 /FpML/trade/fxSingleLeg//currency 時,索引失效。建議:查詢盡量避免 //,使用完整路徑。
連接謂詞無固有類型,DB2 無法確定索引適用性。解決方案:在連接鍵上強制轉型:
where $tdoc/party/partyId/xs:double(.) = $pdoc/PtyID/xs:double(.)
索引類型與轉型函數對照:
| 索引 SQL 類型 | 轉型函數 |
|---|---|
| DOUBLE | xs:double() |
| VARCHAR(n)/HASHED | fn:string() |
| DATE | xs:date() |
| TIMESTAMP | xs:dateTime() |
FpML 文檔常聲明默認命名空間 xmlns="https://www.fpml.org/2007/FpML-4-3"。無命名空間查詢無法匹配帶命名空間文檔。三種應對策略:
*:FpML/*:trade/*:tradeDate —— 兼容有/無命名空間,但語義鬆散XMLNAMESPACES(DEFAULT 'uri') —— 單一命名空間場景首選declare namespace fpml="uri"; $TRADEDOC/fpml:FpML/... —— 多命名空間混合場景最精準無命名空間索引無法覆蓋帶命名空間文檔。兩種等效寫法:
-- 方式 1:顯式前綴
create index thtdns1 on trades(tradedoc) generate keys using XMLpattern
'declare namespace fpml="https://www.fpml.org/2007/FpML-4-3";
/fpml:FpML/fpml:trade/fpml:tradeHeader/fpml:tradeDate' as sql date;
-- 方式 2:默認元素命名空間
create index thtdns2 on trades(tradedoc) generate keys using XMLpattern
'declare default element namespace "https://www.fpml.org/2007/FpML-4-3";
/FpML/trade/tradeHeader/tradeDate' as sql date;
若需同時覆蓋帶/不帶命名空間文檔,使用命名空間通配符:
create index thtdns3 on trades(tradedoc) generate keys using
XMLpattern '/*:FpML/*:trade/*:tradeHeader/*:tradeDate' as sql date;
此索引符合「容量覆蓋」原則,可服務於顯式前綴查詢。