必须先用with schemabinding重建视图并满足两段式表名、显式列名、禁用非确定性函数等硬性要求,再创建唯一聚集索引;否则必然报“view is not schema bound”错误,且需校准ansi_nulls、quoted_identifier等set选项,查询时standard版必须加with (noexpand)才能生效。

不能直接给普通视图加聚集索引,必须先用 WITH SCHEMABINDING 重建视图,再创建唯一聚集索引;否则必然报错 "view is not schema bound"。
CREATE VIEW 必须带 WITH SCHEMABINDING
已有视图如果没加 SCHEMABINDING,CREATE UNIQUE CLUSTERED INDEX 会直接失败。这不是语法可选,而是 SQL Server 的强制前提。
- 所有表引用必须是两段式名称,例如
dbo.Orders,不能写Orders -
SELECT列表不能用*,必须显式列出每一列 - 禁用非确定性函数:
GETDATE()、NEWID()、ISNULL()(若参数是非确定列)、子查询、TOP、UNION、外连接 - 含聚合时,必须用
COUNT_BIG(*)替代COUNT(*),且必须有GROUP BY
建索引前必须校准 SET 选项
哪怕视图定义完全合规,CREATE UNIQUE CLUSTERED INDEX 仍可能报错或后续不生效——根源常在会话级 SET 选项。这些选项必须全为指定值,缺一不可:
-
ANSI_NULLS ON(DB-Library 默认 OFF,容易踩坑) QUOTED_IDENTIFIER ONANSI_WARNINGS ON-
ARITHABORT ON(SSMS 默认开,但很多 ORM 连接池默认关) CONCAT_NULL_YIELDS_NULL ONNUMERIC_ROUNDABORT OFF
建议在建索引前显式执行:SET ANSI_NULLS ON; SET QUOTED_IDENTIFIER ON;,其他项也按需补全。
聚集索引键必须满足数据层硬约束
即使语法和 SET 都对了,建索引仍可能失败,问题往往出在基表结构或视图逻辑上:
- 用于
GROUP BY或连接的列(如ProductID),必须在基表上有主键或唯一非空约束 - 聚集索引键列(如
OrderID)必须出现在视图SELECT列表中,且值全局唯一、非空、确定性 - 不能隐式转换类型,比如视图里把
int和varchar列做等值连接却没显式CAST - 所有引用对象(表、函数)必须在同一数据库内,不能是临时表、表变量或跨库四段名
查询未必自动走索引视图
成功建好 UNIQUE CLUSTERED INDEX 只是第一步。是否真被使用,取决于版本和写法:
- Enterprise / Developer 版本:优化器可能自动匹配,但要求查询谓词覆盖索引键列、统计信息准确、无参数嗅探偏差
- Standard / Express 版本:必须显式引用视图,并加
WITH (NOEXPAND)提示,例如:SELECT * FROM dbo.vw_SalesSummary WITH (NOEXPAND) WHERE ProductID = 123 - 执行计划里看到
Clustered Index Seek/Scan对应的是视图索引,而非Table Scan或Hash Match Aggregate,才算真正命中
最容易被忽略的是:NOEXPAND 提示只在 Standard/Express 下强制生效,而在 Enterprise 下它只是“允许”优化器考虑索引视图——但一旦查询条件漏掉索引键列,照样退化为扫基表。










