创建 XML 索引

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例

本文将介绍如何创建主 XML 索引和辅助 XML 索引。

创建主 XML 索引

要创建主 XML 索引,请使用 CREATE INDEX (Transact-SQL) Transact-SQL DDL 语句。 XML 索引不完全支持可用于非 XML 索引的所有选项。

创建 XML 索引时请注意下列事项:

  • 若要创建主 XML 索引,含有被索引的 XML 列的表(称为基表)必须具有主键的聚集索引。 此聚集索引确保了在对基表进行了分区的情况下,可以使用相同的分区方案和分区函数对主 XML 索引进行分区。

  • 如果存在 XML 索引,则不能修改该表的聚集主键。 在修改主键之前,必须删除表的所有 XML 索引。

  • 您可以对单个 xml 类型列创建主 XML 索引。 不能将 xml 类型列作为键列来创建任何其他类型的索引。 但是,可以在非 XML 索引中包含 xml 类型列。 表中的每个 xml 类型列都可以有自己的主 XML 索引。 但是,一个 xml 类型列只允许有一个主 XML 索引。

  • XML 索引和非 XML 索引存在于相同的命名空间中。 因此,同一表的 XML 索引和非 XML 索引不能具有相同的名称。

  • 对于 XML 索引,IGNORE_DUP_KEY 选项和 ONLINE 选项始终设置为 OFF。 您可以将这些选项的值指定为 OFF。

  • 将用户表的文件组和分区信息应用于 XML 索引,并且不能单独指定。

  • DROP_EXISTING 索引选项可以删除主 XML 索引并创建一个新的主 XML 索引,或者删除辅助 XML 索引并创建一个新的辅助 XML 索引。 但是,此选项不能通过删除辅助 XML 索引来创建新的主 XML 索引,反之亦然。

  • 主 XML 索引名称与视图名称有相同的限制。

    不能对视图中的 xml 类型列、xml 类型列的 table 值变量或 xml 类型变量创建 XML 索引。

  • 若要使用 ALTER TABLE ALTER COLUMN 选项将 xml 类型列从非类型化的 XML 更改为类型化的 XML,或者从类型化的 XML 更改为非类型化的 XML,则列不应存在 XML 索引。 如果确实存在,则在尝试更改列类型之前必须删除该索引。

  • 创建 XML 索引时必须将选项 ARITHABORT 设置为 ON。 要使用 xml 数据类型方法查询、删除、更新 XML 列中的值或向 XML 列中插入值,则必须对连接设置相同的选项。 如果没有设置,则 xml 数据类型方法将会失败。

    注意

    有关 XML 索引的信息可以在目录视图中找到。 但是,不支持 sp_helpindex。 本主题后面部分提供的示例说明了如何查询目录视图以查找 XML 索引信息。

如果 xml 数据类型列包含 XML 架构类型 xs:datexs:dateTime(或这些类型的任何子类型)的值,且这些值中的年份小于 1,则在对这些 XML 数据类型列创建或重新创建主 XML 索引时,索引创建操作在 SQL Server 2008 (10.0.x) 和更高版本中将失败。 SQL Server 2005 (9.x) 允许这些值,因此在 SQL Server 2005 (9.x) 生成的数据库中创建索引时,可能会出现此问题。 有关详细信息,请参阅 类型化的 XML 与非类型化的 XML 的比较

示例:创建主 XML 索引

在大多数示例中,使用的是包含非类型化 XML 列的表 T (pk INT PRIMARY KEY, xCol XML)。 此示例可以采用简单的方式扩展到类型化 XML。 为简化起见,针对 XML 数据实例说明了查询,如下例所示:

<book genre="security" publicationdate="2002" ISBN="0-7356-1588-2">
   <title>Writing Secure Code</title>
   <author>
      <first-name>Michael</first-name>
      <last-name>Howard</last-name>
   </author>
   <author>
      <first-name>David</first-name>
      <last-name>LeBlanc</last-name>
   </author>
   <price>39.99</price>
</book>

下面的语句对表 T 中 XML 列 xCol 创建了一个名为 idx_xCol 的 XML 索引:

CREATE PRIMARY XML INDEX idx_xCol on T (xCol)

创建辅助 XML 索引

使用 CREATE INDEX (Transact-SQL) Transact-SQL DDL 语句可创建辅助 XML 索引并且可指定所需的辅助 XML 索引类型。

创建辅助 XML 索引时请注意下列事项:

  • 除了 IGNORE_DUP_KEY 和 ONLINE 之外,允许对辅助 XML 索引使用所有适用于非聚集索引的索引选项。 对于辅助 XML 索引,这两个选项必须始终设置为 OFF。

  • 辅助索引的分区方式类似于主 XML 索引。

  • DROP_EXISTING 可以删除用户表的辅助索引并为用户表创建其他辅助索引。

可以查询 sys.xml_indexes 目录视图来检索 XML 索引信息。 sys.xml_indexes 目录视图中的 secondary_type_desc 列中提供了辅助索引的类型:

SELECT  *
FROM    sys.xml_indexes;

secondary_type_desc 列中返回的值可以是 NULL、PATH、VALUE 或 PROPERTY。 对于主 XML 索引而言,返回的值为 NULL。

示例:创建辅助 XML 索引

下面的示例说明了如何创建辅助 XML 索引。 此示例还显示了有关您创建的 XML 索引的信息。

CREATE TABLE T (Col1 INT PRIMARY KEY, XmlCol XML);
GO
-- Create primary index.
CREATE PRIMARY XML INDEX PIdx_T_XmlCol
ON T(XmlCol);
GO
-- Create secondary indexes (PATH, VALUE, PROPERTY).
CREATE XML INDEX PIdx_T_XmlCol_PATH ON T(XmlCol)
USING XML INDEX PIdx_T_XmlCol
FOR PATH;
GO
CREATE XML INDEX PIdx_T_XmlCol_VALUE ON T(XmlCol)
USING XML INDEX PIdx_T_XmlCol
FOR VALUE;
GO
CREATE XML INDEX PIdx_T_XmlCol_PROPERTY ON T(XmlCol)
USING XML INDEX PIdx_T_XmlCol
FOR PROPERTY;
GO

可以通过查询 sys.xml_indexes 目录视图来检索 XML 索引信息。 secondary_type_desc 列提供了辅助索引类型。

SELECT  *
FROM    sys.xml_indexes;

您还可以在目录视图中查询索引信息。

SELECT *
FROM sys.xml_indexes
WHERE object_id = object_id('T');

您可以添加示例数据然后查看 XML 索引信息。

INSERT INTO T VALUES (1,
'<doc id="123">
<sections>
<section num="2">
<heading>Background</heading>
</section>
<section num="3">
<heading>Sort</heading>
</section>
<section num="4">
<heading>Search</heading>
</section>
</sections>
</doc>');
GO
-- Check XML index information.
SELECT *
FROM   sys.dm_db_index_physical_stats (db_id(), object_id('T'), NULL, NULL, 'DETAILED');
GO
-- Space usage of primary XML index
DECLARE @index_id int;
SELECT  @index_id = i.index_id
FROM    sys.xml_indexes i
WHERE   i.name = 'PIdx_T_XmlCol' and object_name(i.object_id) = 'T';

SELECT *
FROM sys.dm_db_index_physical_stats (db_id(), object_id('T') , @index_id, DEFAULT, 'DETAILED');
GO
--- Space usage of secondary XML index (for example PATH secondary index)  PIdx_T_XmlCol_PATH
DECLARE @index_id int;
SELECT  @index_id = i.index_id
FROM    sys.xml_indexes i
WHERE  i.name = 'PIdx_T_XmlCol_PATH' and object_name(i.object_id) = 'T';

SELECT *
FROM sys.dm_db_index_physical_stats (db_id(), object_id('T') , @index_id, DEFAULT, 'DETAILED');
GO

-- Space usage of all secondary XML indexes for a particular table
SELECT i.name, object_name(i.object_id), stats.*
FROM   sys.dm_db_index_physical_stats (db_id(), object_id('T'), NULL, DEFAULT, 'DETAILED') stats
JOIN sys.xml_indexes i ON (stats.object_id = i.object_id and stats.index_id = i.index_id)
WHERE secondary_type is not null;
-- Drop secondary indexes.
DROP INDEX PIdx_T_XmlCol_PATH ON T;
GO
DROP INDEX PIdx_T_XmlCol_VALUE ON T;
GO
DROP INDEX PIdx_T_XmlCol_PROPERTY ON T;
GO
-- Drop primary index.
DROP INDEX PIdx_T_XmlCol ON T;
-- Drop table T.
DROP TABLE T;
GO

另请参阅