索引视图必须用 schemabinding 创建,且首个索引必须是 unique clustered;需显式指定两段式表名、列名,禁用 * 和重复列名;set 选项如 ansi_nulls 和 quoted_identifier 必须为 on;查询优化器不一定自动使用该索引。

索引视图必须用 SCHEMABINDING 创建
没加 SCHEMABINDING 的视图,哪怕内容再简单,也不能建索引。SQL Server 会直接报错:无法对视图'v_salary'创建索引,因为该视图未绑定到架构。这个绑定不是可选项,是硬性前提——它强制视图与底层表的 schema(列名、类型、所属 schema)强关联,防止表结构被意外修改导致视图失效。
常见踩坑点:
- 所有引用的表都得带两段式名称,比如
dbo.Salary,写成Salary就失败 - 不能用
*,必须显式列出每一列,否则报错:在绑定到架构的对象中不允许使用语法 '*' - 视图里不能有重复列名,哪怕只是别名重了也不行,报错提示明确说“多次指定了列名”
CREATE UNIQUE CLUSTERED INDEX 是唯一合法的首建索引
给索引视图加的第一个索引,必须是 UNIQUE CLUSTERED 类型。你试 CREATE CLUSTERED INDEX(缺 UNIQUE)或 CREATE NONCLUSTERED INDEX,都会失败,错误信息直白:无法对视图'v_salary'创建索引,它没有唯一聚集索引。
原因在于:索引视图的物理存储依赖于这个唯一聚集索引——它把结果集真正固化进数据库,后续非聚集索引才能在此基础上构建。一旦删掉这个唯一聚集索引,整个物化结果就没了,视图退化回普通视图。
注意:
- 唯一性约束靠你保证,SQL Server 不自动校验数据是否真唯一;如果插入重复键,会像普通唯一索引一样报错
- 建完唯一聚集索引后,才能加非聚集索引,数量上限和普通表一致(最多 999 个)
SET 选项不匹配会导致索引失效或建索引失败
索引视图对会话级 SET 选项极其敏感。比如 CONCAT_NULL_YIELDS_NULL、QUOTED_IDENTIFIER、ANSI_NULLS 等,只要建视图时、建索引时、或者后续任何 DML 操作时这些选项值不一致,轻则查询不走索引,重则建索引直接报错。
最常出问题的是 ANSI_NULLS 和 QUOTED_IDENTIFIER:它们必须为 ON,否则 CREATE VIEW ... WITH SCHEMABINDING 就会失败。而 CONCAT_NULL_YIELDS_NULL 为 OFF 时,即使视图建成了,后续更新基表也可能触发索引维护异常。
建议做法:
- 在建视图和建索引前,显式执行
SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; - 避免在应用连接字符串里覆盖这些设置,尤其 ORM 工具默认可能关掉某些选项
查询优化器不一定自动用上索引视图
即使你成功建好了索引视图,查询优化器也未必会选它——它得判断“用这个物化结果比直接查原表更便宜”。如果外部查询的 WHERE 条件无法下推到视图定义里,或者视图本身太宽(列太多),优化器很可能弃用它。
你可以用 OPTION (EXPAND VIEWS) 强制绕过索引视图,反向验证它是否被命中;也可以查 sys.dm_exec_query_plan 看执行计划里有没有出现视图名对应的物理运算符。
容易忽略的一点:
- 索引视图的列默认继承基表的
large_value_types_out_of_row设置,但如果你用了表达式列(比如UPPER(name)),它的大值类型默认是0(即行内存储),可能影响性能,这点很少有人检查











