解析视图的索引

与任何索引相同,仅当查询优化器确定在 SQL Server 的查询计划中使用索引视图有益时,SQL Server 才会选择这样做。

索引视图可以在任何版本的 SQL Server 中创建。在 SQL Server Enterprise 中,查询优化器会自动考虑索引视图。若要在其他所有版本中使用索引视图,则必须使用 NOEXPAND 表提示。

当满足下列条件时,SQL Server 查询优化器使用索引视图:

  • 下列会话选项均设置为 ON:

    • ANSI_NULLS

    • ANSI_PADDING

    • ANSI_WARNINGS

    • ARITHABORT

    • CONCAT_NULL_YIELDS_NULL

    • QUOTED_IDENTIFIER

    • NUMERIC_ROUNDABORT 会话选项设置为 OFF。

  • 查询优化器查找视图索引列与查询中的元素之间的匹配,例如:

    • WHERE 子句中的搜索条件谓词

    • 联接操作

    • 聚合函数

    • GROUP BY 子句

    • 表引用

  • 估计的索引使用成本是查询优化器考虑使用的所有访问机制中的最低成本。

  • 查询中引用(直接或通过展开视图访问其基础表)的且与索引视图中的表引用相对应的每个表在该查询中都必须具有应用于表的相同提示集。

    注意注意

    在此上下文中,不管当前的事务隔离级别如何,READCOMMITTED 和 READCOMMITTEDLOCK 提示始终被认为是不同的提示。

除 SET 选项和表提示的要求外,查询优化器也使用上述规则确定表索引是否包含查询。不必在查询中指定其他内容即可使用索引视图。

查询不必在 FROM 子句中显式引用索引视图,查询优化器即可使用该索引视图。如果查询所引用的基表中的列也同时存在于索引视图中,并且,查询优化器估计使用索引视图将提供最低成本的访问机制,则查询优化器会选择索引视图,其方式类似于当查询中不直接引用基表索引时选择基表索引。当视图中包含非查询所引用的列时,只要视图提供包含一个或多个查询中所指定列的最低成本选项,查询优化器即可能选择该视图。

查询优化器将 FROM 子句中引用的索引视图视为标准视图。查询优化器在优化进程开始时将视图的定义展开至查询中。然后,执行索引视图匹配。可以将索引视图用于优化器选择的最终执行计划中,或该计划可以通过访问视图引用的基表来具体化由视图得到的必要数据。优化器会选择成本最低的方式。

将提示用于索引视图

您可以使用 EXPAND VIEWS 查询提示防止将视图索引用于查询,也可以使用 NOEXPAND 表提示强制将索引用于查询的 FROM 子句指定的索引视图。但应该让查询优化器动态确定用于每个查询的最佳访问方法。只在经测试证实 EXPAND 和 NOEXPAND 可显著提高性能的特定情形中使用它们。

EXPAND VIEWS 选项指定对于整个查询,查询优化器不应使用任何视图索引。

当为视图指定了 NOEXPAND 时,查询优化器将考虑使用为视图定义的任何索引。通过在可选的 INDEX() 子句中指定 NOEXPAND,可强制查询优化器使用指定索引。只能为索引视图指定 NOEXPAND,而不能为还未创建索引的视图指定 NOEXPAND。

如果在包含视图的查询既未指定 NOEXPAND 也未指定 EXPAND VIEWS,则展开该视图以访问基础表。如果组成视图的查询包含表提示,则这些提示将传播到基础表。(视图解析中详细说明了此过程。)只要视图的基础表中的提示集彼此相同,查询就可以与索引视图进行匹配。在大部分情况下,这些提示彼此匹配,因为它们直接从视图继承而来。但是,如果查询引用表而不是引用视图,且直接应用于这些表的提示并不相同,则这类查询就无法与索引视图进行匹配。如果在视图展开后 INDEX、PAGLOCK、ROWLOCK、TABLOCKX、UPDLOCK 或 XLOCK 提示应用于查询中引用的表,则查询无法与索引视图进行匹配。

如果形式为 INDEX (index_val[ ,...n]) 的表提示引用了查询中的视图,而您还没有指定 NOEXPAND 提示,则忽略该索引提示。若要指定使用特定索引,请使用 NOEXPAND。

通常,查询优化器将索引视图与查询匹配后,对查询中表或视图指定的所有提示都将直接应用于索引视图。如果查询优化器选择不使用索引视图,则所有提示将直接传播到视图中引用的表。有关详细信息,请参阅视图解析。此传播不应用于联接提示。仅在查询中提示的原始位置应用提示。将查询与索引视图匹配时,查询优化器不考虑联接提示。如果查询计划使用了与包含联接提示的查询部分匹配的索引视图,则计划中不使用联接提示。

SQL Server 2008 的索引视图定义中不允许有提示。在 80 和更高的兼容模式中,SQL Server 在维护索引视图定义或执行使用索引视图的查询时将忽略索引视图定义内的提示。尽管在 80 兼容模式中,在索引视图定义中使用提示不会生成语法错误,当仍忽略提示。