辅助 XML 索引
为了增强搜索性能,可以创建辅助 XML 索引。必须有了主 XML 索引才能创建辅助索引。辅助索引的类型如下:
PATH 辅助 XML 索引
VALUE 辅助 XML 索引
PROPERTY 辅助 XML 索引
以下为创建一个或多个辅助索引的一些准则:
如果工作负荷对 XML 列大量使用路径表达式,则 PATH 辅助 XML 索引可能会提高工作负荷的处理速度。最常见的情况是在 Transact-SQL 的 WHERE 子句中对 XML 列使用 exist() 方法。
如果工作负荷通过使用路径表达式从单个 XML 实例中检索多个值,则在 PROPERTY 索引中聚集各个 XML 实例中的路径可能会很有用。这种情况通常出现在属性包方案中,此时提取对象的属性并且已知其主键值。
如果工作负荷涉及查询 XML 实例中的值,但不知道包含那些值的元素名称或属性名称,则您可能希望创建 VALUE 索引。这通常出现在 descendant 轴查找中,例如 //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,仅指定一个路径
或
- /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> 元素。
以下查询从 Contact 表中返回 ContactID。WHERE 子句指定一个筛选器,该筛选器查找 AdditionalContactInfoxml 类型列中的值。只有当相应的其他联系信息 XML 二进制大型对象包含具体的电话号码时,才会返回联系 ID。由于 <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 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、Path 和节点值)创建的,其中 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 索引: