XML 索引 (SQL Server)

可以在数据类型列上 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 BLOB xml 的切碎和持久表示形式。 对于列中每个 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> 说明。

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>元素及其子树,并使用query()方法将其转换为 XML 二进制大型对象。

请注意,检索完整 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”],其中 <作者> 元素可以在层次结构的任何级别发生。 它还发生在通配符查询中,例如 /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"] 其中,查询查找 <book> 具有值 "someValue"的某些属性的元素。

以下查询从Contact表返回ContactID。 该 WHERE 子句指定一个筛选器,用于查找类型列中的值 AdditionalContactInfo``xml 。 仅当相应的附加联系人信息 XML 二进制大型对象包含特定电话号码时,才会返回联系人 ID。 < 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> 的搜索值是已知的,但它可以出现在 XML 实例中作为 <telephoneNumber> 元素的任意子元素。 此类查询可能受益于基于特定值的索引查找。

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 中,索引为“type”3。 名称列包含 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)