SCHEMABINDING 是 SQL Server 强制要求用于索引视图的绑定机制,以锁定依赖对象结构、确保数据一致性;不加则无法创建唯一聚集索引,且需两段式引用、确定性表达式及严格函数限制。
SCHEMABINDING 是什么,为什么必须加
SQL Server 的 indexed view 必须带 SCHEMABINDING,否则根本建不了唯一聚集索引。这不是可选项,是引擎强制要求——因为 indexed view 的物理数据要和基表保持强一致性,SQL Server 需要通过 schema binding 锁定所依赖的表、列、函数定义,防止后续有人改表结构(比如删列、改类型)导致索引数据逻辑错乱或查询失败。
常见错误:Cannot create index on view 'dbo.vSalesSummary' because the view is not schema-bound.
- 声明 view 时必须写
WITH SCHEMABINDING,且所有引用对象(表、函数)都要用两段式名称,比如dbo.Sales,不能只写Sales - 不能引用临时表、表变量、TVF(除非是内联 TVF 且也带 SCHEMABINDING)、系统视图或跨库对象
- 如果基表上有计算列,该列表达式也必须满足 deterministic(确定性),否则
SCHEMABINDING会拒绝创建
indexed view 能用哪些函数和表达式
不是所有 SQL 写法都能放进 indexed view。SQL Server 对 deterministic 和 precision 有严格限制,否则无法保证索引数据在不同执行路径下一致。
- 禁止非确定性函数:
GETDATE()、NEWID()、@@ROWCOUNT、HOST_NAME()等直接报错 -
ISNULL()可用,但COALESCE()在部分旧版本中可能被判定为 non-deterministic(尤其含子查询时),建议统一用ISNULL() - 聚合必须包含
GROUP BY所有非聚合列,且不能漏掉GROUP BY中的列(比如写了SELECT a, SUM(b) FROM t GROUP BY a是合法的;但漏掉a或多加未分组列就失败) - 不能用
TOP、ROW_NUMBER()、窗口函数、UNION ALL(除非所有分支都满足 indexed view 规则且无重复列名)
为什么查询不走 indexed view 的索引
即使你成功建好了带唯一聚集索引的 view,查询也不一定自动命中它。SQL Server 查询优化器默认“忽略” indexed view,除非显式启用或满足严苛条件。