XML 索引可以在數據類型數據行上 xml 建立。 它們會索引數據行中 XML 實例的所有標記、值和路徑,並讓查詢效能受益。 在下列情況下,您的應用程式可能會受益於 XML 索引:
您工作負載中常見的 XML 資料行查詢。 數據修改期間必須考慮 XML 索引維護成本。
您的 XML 值相對較大,且擷取的元件相對較小。 建置索引可避免在運行時間剖析整個數據,並有利於索引查閱以有效率地處理查詢。
XML 索引分為下列類別:
主要 XML 索引
次要 XML 索引
類型數據行上的 xml 第一個索引必須是主要 XML 索引。 使用主要 XML 索引時,支援下列類型的次要索引:PATH、VALUE 和 PROPERTY。 根據查詢的類型,這些次要索引可能有助於改善查詢效能。
備註
除非已正確設定資料庫選項以使用 xml 數據類型,否則您無法建立或修改 XML 索引。 如需詳細資訊,請參閱 使用 Full-Text 搜尋搭配 XML 資料行。
XML 實例會以大型二進位物件的形式儲存在類型數據行中 xml (BLOB)。 這些 XML 實例可能很大,而且數據類型實例的 xml 儲存的二進位表示法最多可達 2 GB。 如果沒有索引,這些二進位大型物件會在運行時間分割以評估查詢。 這個粉碎可能很耗時。 例如,請考慮下列查詢:
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS "PD")
SELECT CatalogDescription.query('
/PD:ProductDescription/PD:Summary
') as Result
FROM Production.ProductModel
WHERE CatalogDescription.exist ('/PD:ProductDescription/@ProductModelID[.="19"]') = 1
若要選取符合 子句中條件的 WHERE XML 實例,數據表中每個數據 Production.ProductModel 列中的 XML 二進位大型物件 (BLOB) 會在運行時間進行切割。 然後,會評估 方法中的exist()運算式 (/PD:ProductDescription/@ProductModelID[.="19"]。 視儲存在數據行中的實例大小和數目而定,此運行時間切割的成本可能很高。
在您的應用程式環境中,如果查詢 XML 二進位大型物件(BLOB)很常見,為 xml 類型的欄位編製索引是有幫助的。 不過,在數據修改期間,維護索引會產生成本。
主要 XML 索引
主要 XML 索引會索引 XML 資料行中 XML 實例內的所有標記、值和路徑。 若要建立主要 XML 索引,發生 XML 資料行的數據表必須具有數據表主鍵上的叢集索引。 SQL Server 會使用此主鍵,將主要 XML 索引中的數據列與包含 XML 數據行之數據表中的數據列相互關聯。
主要 XML 索引是 xml 資料類型欄位中 XML BLOB 的分解和保存表示。 針對數據行中的每個 XML 二進位大型物件 (BLOB),索引會建立數個數據列。 索引中的數據列數目大約等於 XML 二進位大型物件中的節點數目。 當查詢擷取完整的 XML 實例時,SQL Server 會從 XML 資料行提供 實例。 XML 實例內的查詢會使用主要 XML 索引,而且可以使用索引本身傳回純量值或 XML 子樹。
每個資料列都會儲存下列節點資訊:
標記名稱,例如元素或屬性名稱。
節點值。
節點類型,例如項目節點、屬性節點或文字節點。
文件順序資訊,以內部節點識別符表示。
從每個節點到 XML 樹狀結構根目錄的路徑。 此數據行會在查詢中搜尋路徑表達式。
基表的主鍵。 基表的主鍵在與基表背聯結的主要 XML 索引中重複,而基表主鍵中的數據行數目上限限製為 15。
此節點資訊可用來評估及建構指定查詢的 XML 結果。 為了優化目的,標籤名稱和節點類型資訊會編碼為整數值,而Path資料行會使用相同的編碼方式。 此外,路徑是以反向順序儲存的,這樣在只知道路徑後綴的情況下,也可以進行比對。 例如:
-
//ContactRecord/PhoneNumber其中只有最後兩個步驟已知
或者
-
/Book/*/Title其中通配符 (*) 是在表示式中間指定。
查詢處理器會針對涉及 xml 數據類型方法的 查詢使用主要 XML 索引,並從主要索引本身傳回純量值或 XML 子樹。 (此索引會儲存重建 XML 實例所需的所有資訊。
例如,下列查詢會傳回儲存在 CatalogDescription``xml 數據表中類型數據行中的 ProductModel 摘要資訊。 查詢只針對目錄描述中也儲存<Features>描述的產品模型,傳回<Summary>資訊。
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS "PD")SELECT CatalogDescription.query(' /PD:ProductDescription/PD:Summary') as ResultFROM Production.ProductModelWHERE CatalogDescription.exist ('/PD:ProductDescription/PD:Features') = 1
至於主要 XML 索引,而不是將基表中的每個 XML 二進位大型物件實例分割,對應至每個 XML 二進位大型物件的索引行會依序搜尋,以尋找方法中指定的 exist() 表達式。 如果在索引的Path欄位中找到路徑,則會從主要 XML 索引擷取<Summary>元素及其子樹,並轉換成 XML 二進位大型物件,做為query()方法的結果。
請注意,擷取完整 XML 實例時,不會使用主要 XML 索引。 例如,下列查詢會從數據表中擷取整個 XML 實例,以描述特定產品模型的製造指示。
USE AdventureWorks2012;SELECT InstructionsFROM Production.ProductModel WHERE ProductModelID=7;
次要 XML 索引
若要增強搜尋效能,您可以建立次要 XML 索引。 您必須先存在主要 XML 索引,才能建立次要索引。 以下是類型:
PATH 次要 XML 索引
VALUE 次要 XML 索引
PROPERTY 次要 XML 索引
以下是建立一或多個次要索引的一些指導方針:
如果您的工作負載在 XML 數據行上大幅使用路徑表示式,PATH 次要 XML 索引可能會加速您的工作負載。 最常見的案例是在 Transact-SQL 的 WHERE 子句中,在 XML 數據行上使用 exist() 方法。
如果您的工作負載使用路徑表達式從個別 XML 實例擷取多個值,那麼在 PROPERTY 索引中將每個 XML 實例內的路徑進行叢集可能會很有幫助。 當擷取對象的屬性,且其主鍵值已知時,通常會在屬性包案例中發生此案例。
如果您的工作負載牽涉到查詢 XML 實例內的值,而不知道包含這些值的元素或屬性名稱,您可能想要建立 VALUE 索引。 這通常會發生在後代軸查閱中,例如 //author[last-name="Howard"],其中<author>元素可以在任何層級的階層中出現。 它也會發生在通配符查詢中,例如 /book [@* = “novel”],其中查詢會尋找 <具有 “novel” 值之某些屬性的書籍> 元素。
PATH 次要 XML 索引
如果您的查詢通常會在類型數據行上 xml 指定路徑表達式,PATH 次要索引或許可以加速搜尋。 如本主題稍早所述,當在 WHERE 子句中指定 exist() 方法時,主要索引在查詢中會很有用。 如果您新增PATH次要索引,您也可以改善這類查詢中的搜尋效能。
雖然主要 XML 索引避免在運行時間必須粉碎 XML 二進位大型物件,但它可能無法根據路徑表示式提供查詢的最佳效能。 由於對應至 XML 二進位大型物件之主要 XML 索引中的所有數據列會循序搜尋大型 XML 實例,因此循序搜尋速度可能會很慢。 在此情況下,在主要索引的路徑值和節點值上建置次要索引可以大幅加快索引搜尋的速度。 在PATH次要索引中,路徑和節點值是索引鍵數據行,可在搜尋路徑時提供更有效率的搜尋。 查詢優化器可能會針對表示式使用 PATH 索引,例如以下所示:
-
/root/Location只指定路徑
或者
-
/root/Location/@LocationID[.="10"]其中指定路徑和節點值。
下列查詢顯示PATH索引有助於的位置:
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS "PD")
SELECT CatalogDescription.query('
/PD:ProductDescription/PD:Summary
') AS Result
FROM Production.ProductModel
WHERE CatalogDescription.exist ('/PD:ProductDescription/@ProductModelID[.="19"]') = 1
在查詢中,方法中的exist()路徑表達式/PD:ProductDescription/@ProductModelID和值"19"會對應至PATH索引的索引鍵欄位。 這允許在PATH索引中直接搜尋,並提供比主要索引中路徑值的循序搜尋更好的搜尋效能。
VALUE 次級 XML 索引
如果查詢是以值為基礎,例如 /Root/ProductDescription/@*[. = "Mountain Bike"] 或 //ProductDescription[@Name = "Mountain Bike"],且路徑未完全指定,或包含通配符,您可以建置以主要 XML 索引中的節點值為基礎的次要 XML 索引,以更快取得結果。
VALUE 索引的關鍵欄位是主要 XML 索引的節點值和路徑。 如果您的工作負載涉及從 XML 實例查詢值,而不知道包含值的元素或屬性名稱,VALUE 索引可能很有用。 例如,下列表達式將受益於具有 VALUE 索引:
//author[LastName="someName"]您知道 <LastName> 元素的值,但 <author> 父元素可以在任何地方出現。/book[@* = "someValue"]其中查詢會尋找具有某個屬性且屬性值為"someValue"的<book>元素。
zh-TW: 下列查詢會從 Contact 表格中返回 ContactID。
WHERE 條件指定在 AdditionalContactInfo``xml 類型欄中尋找值的篩選器。 只有在對應的其他連絡資訊 XML 二進位大型物件包含特定電話號碼時,才會傳回聯繫人標識符。 由於<telephoneNumber>元素可能會在 XML 中的任何位置出現,因此路徑表示式會指定子代或自身軸。
WITH XMLNAMESPACES (
'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo' AS CI,
'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes' AS ACT)
SELECT ContactID
FROM Person.Contact
WHERE AdditionalContactInfo.exist('//ACT:telephoneNumber/ACT:number[.="111-111-1111"]') = 1
在此情況下,搜尋值 <number> 是已知的,但它可以作為元素 <telephoneNumber> 的子元素出現在 XML 實例中的任何位置。 這種查詢可能會受益於以特定值為基礎的索引查閱。
PROPERTY 次級索引
從個別 XML 實例擷取一或多個值的查詢可能會受益於 PROPERTY 索引。 當您使用 xml 型別的 value() 方法來擷取物件屬性,且已知該物件的主鍵值時,就會發生此情況。
PROPERTY 索引是以主要 XML 索引的數據行(PK、路徑和節點值)為基礎,其中 PK 是基表的主鍵。
例如,針對產品模型19,下列查詢會使用 value() 方法擷取 ProductModelID 和 ProductModelName 屬性值。 PROPERTY 索引可能會提供更快的執行速度,而不是使用主要 XML 索引或其他次要 XML 索引。
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS "PD")
SELECT CatalogDescription.value('(/PD:ProductDescription/@ProductModelID)[1]', 'int') as ModelID,
CatalogDescription.value('(/PD:ProductDescription/@ProductModelName)[1]', 'varchar(30)') as ModelName
FROM Production.ProductModel
WHERE ProductModelID = 19
除了本主題稍後所述的差異之外,在類型數據行上xml 建立 XML 索引類似於在非xml 類型數據行上建立索引。 下列 Transact-SQL DDL 語句可用來建立和管理 XML 索引:
取得 XML 索引的相關信息
XML 索引項目會出現在目錄檢視 sys.indexes 中,索引類型 3。 name 欄位包含 XML 索引的名稱。
XML 索引也會記錄在目錄檢視中,sys.xml_indexes。 這包含 sys.indexes 的所有資料行,以及一些適用於 XML 索引的特定數據行。 數據行中的 NULL 值secondary_type,表示主要 XML 索引;值 『P』、『R』 和 'V' 分別代表 PATH、PROPERTY 和 VALUE 次要 XML 索引。
您可以在資料表值函數 sys.dm_db_index_physical_stats 中找到 XML 索引之空間使用。 它提供的資訊,例如所有索引類型所佔用的磁碟頁數、平均數據列大小,以及記錄數目。 這也包含 XML 索引。 此資訊適用於每個資料庫分割區。 XML 索引使用基表的相同資料分割配置和數據分割函數。
另請參閱
sys.dm_db_index_physical_stats (Transact-SQL)
XML 資料 (SQL Server)