码迷,mamicode.com
首页 > 其他好文 > 详细

创建Indexed View

时间:2016-07-21 15:01:26      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:

传统的 view 是query block的定义,在引用view时,SQL Server将view展开,替换成其定义,用于简化sql 查询语句。相比之下,Indexed View 能够提升查询性能。创建Indexed View的过程十分简单,仅需要在view上创建一个unique clustered index。

The first index created on a view must be a unique clustered index. After the unique clustered index has been created, you can create more nonclustered indexes. Creating a unique clustered index on a view improves query performance because the view is stored in the database in the same way a table with a clustered index is stored. The query optimizer may use indexed views to speed up the query execution.

一,Requirements

1,underlying view 必须满足一定的条件:

  • Verify that the view definition is deterministic.

  • The view must be created by using the WITH SCHEMABINDING option.

  • Tables must be referenced by two-part names, schema.tablename in the view definition.

  • If GROUP BY is present, the VIEW definition must contain COUNT_BIG(*) and must not contain HAVING. These GROUP BY restrictions are applicable only to the indexed view definition. A query can use an indexed view in its execution plan even if it does not satisfy these GROUP BY restrictions.

  • If the view definition contains a GROUP BY clause, the key of the unique clustered index can reference only the columns specified in the GROUP BY clause.

2,Deterministic Views

The definition of an indexed view must be deterministic. A view is deterministic if all expressions in the select list, as well as the WHERE and GROUP BY clauses, are deterministic. Deterministic expressions always return the same result any time they are evaluated with a specific set of input values. Only deterministic functions can participate in deterministic expressions. For example, the DATEADD function is deterministic because it always returns the same result for any given set of argument values for its three parameters. GETDATE is not deterministic because it is always invoked with the same argument, but the value it returns changes each time it is executed.

To determine whether a view column is deterministic, use the IsDeterministic property of the COLUMNPROPERTY function. To determine if a deterministic column in a view with schema binding is precise, use the IsPrecise property of the COLUMNPROPERTY function. COLUMNPROPERTY returns 1 if TRUE, 0 if FALSE, and NULL for input that is not valid. This means the column is not deterministic or not precise.

Even if an expression is deterministic, if it contains float expressions, the exact result may depend on the processor architecture or version of microcode. To ensure data integrity, such expressions can participate only as non-key columns of indexed views. Deterministic expressions that do not contain float expressions are called precise. Only precise deterministic expressions can participate in key columns and in WHERE or GROUP BY clauses of indexed views.

 

二,Example 

 1,创建一个普通的view

create view dbo.view_AllUserLocations
WITH SCHEMABINDING  
as 

SELECT DISTINCT
    Location
FROM dbo.DimUser(NOLOCK)
WHERE Location IS NOT NULL

2,在view上创建unique clustered index,使其转变为Indexed View

create unique clustered index cix_view_AllUserLocations
on dbo.view_AllUserLocations(Location);

抛出错误信息:

Cannot create index on view "testdb.dbo.view_AllUserLocations" because it contains the DISTINCT keyword. Consider removing DISTINCT from the view or not indexing the view. Alternatively, consider replacing DISTINCT with GROUP BY or COUNT_BIG(*) to simulate DISTINCT on grouping columns.

3,使用group by 子句来代替Distinct 子句

create view dbo.view_AllUserLocations
WITH SCHEMABINDING  
as 

SELECT 
    Location
FROM dbo.DimUser(NOLOCK)
WHERE Location IS NOT NULL
GROUP BY Location

抛出错误信息:

Cannot create index on view ‘testdb.dbo.view_AllUserLocations‘ because its select list does not include a proper use of COUNT_BIG. Consider adding COUNT_BIG(*) to select list.

4,在select 子句中增加count_big(*) 子句

create view dbo.view_AllUserLocations
WITH SCHEMABINDING  
as 

SELECT 
    Location,COUNT_BIG(*) as cnt
FROM dbo.DimUser(NOLOCK)
WHERE Location IS NOT NULL
GROUP by Location

Indexed View创建成功

三,默认情况下,Query Processor会展开Indexed View的定义。

有时,Query Optimizer 直接访问 Indexed View,查询性能更有效率。使用 with(NoExpand) 强制Query Processor 直接引用 Indexed View,不展开Indexed View的定义。Query Optimizer直接访问Indexed view,将其看作是一个B-Tree。

from [dbo].[view_AllUserLocations] with(NOEXPAND)

有时,Query Optimizer展开Indexed View的定义,将 view 替换成其定义,能够使查询语句执行效率更高,使用 optin(Expand Views)能够强制Query Processor展开Indexed View的定义。由于展开的动作是在Query Optimizer编译query plan之前进行的,这使得Query Optimizer不会局限于view的定义,而对整个查询语句进行优化,例如调整Join的顺序等。

from [dbo].[view_AllUserLocations] 
inner join .....
option(EXPAND VIEWS)

Appendix

To prevent the Database Engine from using indexed views, include the OPTION (EXPAND VIEWS) hint on the query. Also, if any of the listed options are incorrectly set, this will prevent the optimizer from using the indexes on the views.

Query Hint :EXPAND VIEWS

Specifies that the indexed views are expanded and the query optimizer will not consider any indexed view as a substitute for any part of the query. A view is expanded when the view name is replaced by the view definition in the query text.

This query hint virtually disallows direct use of indexed views and indexes on indexed views in the query plan.

The indexed view is not expanded only if the view is directly referenced in the SELECT part of the query and WITH (NOEXPAND) or WITH (NOEXPAND, INDEX( index_value [ ,...n ] ) ) is specified.

Only the views in the SELECT part of statements, including those in INSERT, UPDATE, MERGE, and DELETE statements are affected by the hint.

Table Hint: NOEXPAND              

Specifies that any indexed views are not expanded to access underlying tables when the query optimizer processes the query. The query optimizer treats the view like a table with clustered index. NOEXPAND applies only to indexed views.


参考doc:

Create Indexed Views

Query Hints (Transact-SQL)

Table Hints (Transact-SQL)

创建Indexed View

标签:

原文地址:http://www.cnblogs.com/ljhdo/p/5691378.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!