必须先用with schemabinding创建视图并满足两段式表名、禁用非确定性函数等硬性要求,再创建唯一聚集索引;否则必然报“view is not schema bound”错误。

视图必须先用 WITH SCHEMABINDING 创建
直接对已有普通视图执行 CREATE UNIQUE CLUSTERED INDEX 必然失败,报错 “view is not schema bound”。SQL Server 强制要求索引视图必须绑定底层表结构,防止列被删、改或重命名导致视图逻辑失效。
常见错误是沿用旧视图定义,漏掉 WITH SCHEMABINDING。重建时注意:
- 所有表引用必须带两段式名称(如
dbo.Orders),不能省略 schema - 不能用
*,必须显式列出每一列 - 不能含
GETDATE()、NEWID()、子查询、TOP、UNION或外连接 - 若含聚合,必须用
COUNT_BIG(*)替代COUNT(*),且必须有GROUP BY
基表和 SELECT 列需满足硬性约束
即使加了 SCHEMABINDING,建索引仍可能报 “不满足索引视图要求”,根源常在数据层。
关键检查点:
- 用于
GROUP BY或连接的列(如ProductID)必须在基表上有主键或唯一非空约束 - 聚集索引键列(如
OrderID)必须在视图SELECT列表中明确出现,且值全局唯一、非空、确定性 - 不能在视图中使用非确定性函数(如
ISNULL()包裹非确定列)、计算列或隐式转换 - 所有引用对象(表、函数)必须在同一数据库内,不能是临时表或表变量
会话 SET 选项必须全部正确
建索引前、建索引时、后续查询时,以下选项必须为指定值,否则会报错或索引不生效:
-
ANSI_NULLS= ON(默认 OLE DB/ODBC 是 ON,但 DB-Library 是 OFF) -
QUOTED_IDENTIFIER= ON -
ANSI_WARNINGS= ON -
ARITHABORT= ON(尤其重要:SSMS 默认 ON,但部分 ORM 或连接池可能关掉) -
CONCAT_NULL_YIELDS_NULL= ON -
NUMERIC_ROUNDABORT= OFF
建议在建索引前显式执行:SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON; ...
查询未必自动走索引视图
成功建好 UNIQUE CLUSTERED INDEX 只是第一步。优化器是否实际使用它,取决于版本和写法:
- Enterprise / Developer 版本:可能自动匹配,但前提是查询谓词覆盖索引列、无参数嗅探偏差、统计信息准确
- Standard / Express 版本:必须显式引用视图,并加
WITH (NOEXPAND)提示,例如:SELECT * FROM dbo.vw_SalesSummary WITH (NOEXPAND) WHERE ProductID = 123 - 即使加了
NOEXPAND,若WHERE条件列不在聚集索引键中,仍可能退化为扫描基表 - 执行计划里看到
Clustered Index Seek/Scan对应的是视图索引,而非Table Scan或Hash Match Aggregate,才算真正命中
最易被忽略的是 ARITHABORT 和 NOEXPAND —— 它们不报错,但让索引形同虚设。











