Share via


次要 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" 值的 <book> 元素。

PATH 次要 XML 索引

如果您的查詢通常會在 xml 類型資料行上指定路徑運算式,則使用 PATH 次要索引將可使搜尋速度變快。如本主題前面所述,當您具有在 WHERE 子句中指定 exist() 方法的查詢時,主索引就非常有用。如果您加入 PATH 次要索引,也可以改善這類查詢的搜尋效能。

雖然主要 XML 索引可避免必須在執行階段切割 XML 二進位大型物件,但是它可能無法為以路徑運算式為基礎的查詢提供最佳的效能。由於會針對大型 XML 執行個體,循序搜尋與 XML 二進位大型物件相對應的主要 XML 索引中的所有資料列,因此循序搜尋可能會很慢。在此情況下,將次要索引建立在主要索引的路徑值與節點值上,將可大幅增加索引搜尋的速度。在 PATH 次要索引中,路徑與節點值都是索引鍵資料行,可在搜尋路徑時進行更有效率的搜尋。查詢最佳化工具可以針對如下列所示的運算式使用 PATH 索引:

  • 在 /root/Location 中只指定一個路徑

OR

  • 在 /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> 元素。

下列查詢會從 Person 資料表傳回 BusinessEntityID。WHERE 子句可指定篩選,以便尋找 AdditionalContactInfoxml 類型資料行中的值。如果對應的其他連絡資訊 XML 二進位大型物件包含特定的電話號碼,就會傳回商業實體識別碼。因為 <telephoneNumber> 元素有可能出現在 XML 的任何位置,所以路徑運算式會指定 descendent-or-self 軸。

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 BusinessEntityID 
FROM   Person.Person
WHERE  AdditionalContactInfo.exist('//ACT:telephoneNumber/ACT:number[.="111-111-1111"]') = 1

在此情況下,雖然已得知 <number> 的搜尋值,但它有可能以 <telephoneNumber> 元素的子系出現在 XML 執行個體中的任何位置。此類的查詢可從以特定值為基礎的索引查閱獲益。

PROPERTY 次要索引

從個別 XML 執行個體擷取一或多個值的查詢可從 PROPERTY 索引獲益。當您使用 xml 類型的 value() 方法來擷取物件屬性,以及當物件的主索引鍵值為已知時,就會發生此情況。

PROPERTY 索引是建立在主要 XML 索引的資料行 (PK、Path 以及節點值) 上,在主要 XML 索引中 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 索引: