必须用with schemabinding创建视图才能加索引,因其强制绑定底层表结构,防止改名、删列或删表导致视图失效;同时要求ansi_nulls和quoted_identifier为on,且首个索引必须是unique clustered。

必须先用 WITH SCHEMABINDING 创建视图,之后才能加索引;漏掉这一步,CREATE UNIQUE CLUSTERED INDEX 会直接报错。
为什么必须用 SCHEMABINDING?
SQL Server 要求索引视图绑定到底层表结构,防止表被意外改名、删列或删表导致视图失效。一旦用了 SCHEMABINDING,你就不能:
– 直接 DROP 或 ALTER 视图引用的基表
– 对基表执行影响列定义的 ALTER TABLE ... DROP COLUMN
– 把表移出当前数据库或换所有者
这些限制不是 bug,是保障索引视图物理存储一致性所必需的。
创建前必须检查的 SET 选项
如果会话的 ANSI_NULLS 或 QUOTED_IDENTIFIER 是 OFF,CREATE VIEW ... WITH SCHEMABINDING 会失败。常见错误信息是:Cannot create index on view 'xxx' because the view is not schema bound.
这不是语法问题,而是当前会话设置不满足要求。解决方法很简单:
- 在 SSMS 中执行
SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON;再运行建视图语句 - 如果用 ODBC 或 .NET 连接,需在连接字符串里显式指定
ANSI Nulls=true - 注意:DB-Library 默认是 OFF,已淘汰,但遗留脚本仍可能踩坑
CREATE UNIQUE CLUSTERED INDEX 必须是第一个索引
索引视图只允许一个聚集索引,且必须是唯一(UNIQUE)+ 聚集(CLUSTERED)。这个索引决定了视图数据的物理存储顺序,后续可追加非聚集索引,但不能另建第二个聚集索引。典型写法:
CREATE UNIQUE CLUSTERED INDEX IX_vw_SalesSummary ON vw_SalesSummary (SalesYear, ProductID);
注意:
– 索引键列必须全部来自视图 SELECT 列表(不能是计算列,除非该计算列是确定性且有精确类型)
– 如果视图含 GROUP BY,通常得用聚合列 + 分组列组合做键,否则唯一性校验通不过
– INCLUDE 子句可用,但不会影响聚集索引的排序逻辑
DML 性能下降是真实代价
索引视图不是“只读加速器”。只要底层表发生 INSERT/UPDATE/DELETE,SQL Server 就要同步维护所有依赖它的索引视图——包括更新其聚集索引 B-Tree 和所有非聚集索引。这意味着:
– 单条 UPDATE 可能触发多个索引视图的级联更新
– 如果某张表被 5 个复杂索引视图引用,DML 响应时间可能翻倍甚至超时
– 查询计划里会出现 Index Spool 或大量 Clustered Index Update 操作符
上线前务必在真实数据量下压测 DML 场景,别只看 SELECT 性能。










