必须先创建带 WITH SCHEMABINDING 的聚合视图并建唯一聚集索引,否则失败;因SQL Server强制要求:视图需架构绑定、禁用非确定性函数、用 COUNT_BIG(*)、GROUP BY 列须有唯一约束、标识符两段式。

不能直接给普通视图加索引——必须先创建带 WITH SCHEMABINDING 的合规聚合视图,再建唯一聚集索引,否则必然失败。
为什么 CREATE UNIQUE CLUSTERED INDEX 总报错?
根本不是语法写错了,而是 SQL Server 对索引视图有一套硬性校验规则,缺一不可:
-
CREATE VIEW必须显式包含WITH SCHEMABINDING,否则提示Cannot create index on view ... because the view is not schema bound - SELECT 列中禁用非确定性函数:如
GETDATE()、NEWID()、ISNULL()(除非底层列允许 null 且函数是确定性的) - 聚合必须用
COUNT_BIG(*),不能用COUNT(*);SUM()、AVG()等需确保操作列非空或已处理 null -
GROUP BY必须覆盖所有参与连接/筛选的关键列,且基表对应列要有唯一约束(主键或唯一非空索引) - 所有表名、列名必须两段式(如
dbo.Sales.ProductID),不能省略 schema
如何写出最小合规的聚合索引视图?
以统计每个产品销售总额和订单数为例,以下结构是能成功建索引的底线:
CREATE VIEW dbo.vw_SalesSummary WITH SCHEMABINDING AS SELECT ProductID, COUNT_BIG(*) AS TotalOrders, SUM(Quantity) AS TotalQuantity, SUM(Quantity * UnitPrice) AS TotalRevenue FROM dbo.Sales GROUP BY ProductID;
关键点:
-
ProductID在dbo.Sales表上必须有主键或唯一非空约束 - 没用
*,没用子查询,没用TOP或ORDER BY - 所有计算列(如
Quantity * UnitPrice)都基于确定性表达式 - 建完后立刻执行:
CREATE UNIQUE CLUSTERED INDEX IX_vw_SalesSummary ON dbo.vw_SalesSummary (ProductID)
查询时怎么真正用上这个索引视图?
索引视图不会自动被所有查询命中,尤其在 Standard / Express 版本中:
- Enterprise / Developer 版本下,优化器可能自动匹配,但前提是查询谓词与视图定义高度对齐(比如 WHERE 条件列正好是视图的
GROUP BY列) - 其他版本必须显式引用视图,并强制使用:
SELECT * FROM dbo.vw_SalesSummary WITH (NOEXPAND) WHERE ProductID = 123 - 如果上层查询加了
ORDER BY TotalRevenue,但视图定义里没把该列放进索引键或INCLUDE,仍会退化为扫描基表 - 验证是否生效:看执行计划里出现的是
Clustered Index Seek/Scan(对应视图索引),而不是Table Scan或Hash Match(对应基表)
最容易被忽略的一点:即使视图建好了、索引也建成功了,只要调用时没加 WITH (NOEXPAND),SQL Server 就可能把它当普通视图展开,完全绕过预计算结果——亿级数据的聚合代价又全回来了。

















