在视图上建的第一个索引必须是聚集索引,因为聚集索引的叶级包含了所有数据,此索引实际上确实对视图进行了物化(持久化存储)。视图的数据被物理地存储在聚焦索引的叶级别中。
索引视图要求所有用到的函数都必须是确实性的。且视图定义不能包含任何下列元素:
- TOP
- text、ntext或者image字段
- DISTINCT
- MIN、MAX、COUNT(*)、COUNT(<表达式>)、STDEV、VARIANCE、AVG
- 可空类型的表达式上进行SUM
- 派生表
- ROWSET 函数
- 其它视图(只能引用基准表)
- UNION
- 子查询、OUTER连接或者自连接
- 全文索引谓词(CONTAINS、FREETEXT)
- COMPUTE,COMPUTE BY
- ORDER BY
如果视图定义包含GROUP BY,就必须在SELECT列表中包括聚合函数COUNT_BIG(*)。COUNT_BIG会返回BIGINT数据类型的值,是一个8字节长整型。含有GROUP BY子句的视图不能包含HAVING、CUBE、ROLLUP 或者GROUP BY ALL。所有的GROUP BY字段也必须出现在SELECT列表中。注意:如果视图包含了SUM和COUNT_BIG(*),即使索引视图中不允许AVG函数,仍然可以计算得到等价于AVG函数的结果。尽管这些限制可能看起来十分严格,但是谨记它们只是针对视图的定义,而并不针对可能使用索引视图的那些查询。
可以使用OBJECTPROPERTY函数的IsIndexable属性来检验是否已经满足了所有需求。下面查询反映了是否可以一张名为ProductTotals的视图上创建索引。
SELECT ObjectProperty(object_id('productTotals'), 'IsIndexable')
创建索引视图:
--注意下面的“WITH SCHEMABINDING”子句以及表中指明的架构名称(dbo)。 CREATE VIEW v_test_news WITH SCHEMABINDING AS SELECT NewsId,CASE WHEN NewsUrl<>'' AND IsDelete=0 AND IsVerify=1 ANDIsUserPost=0 THEN 1 ELSE 0 END AS IsShow FROM dbo.news创建索引:
CREATE UNIQUE clustered INDEX idx_v_main ON v_test_news(NewsId)