我一直在SQL Server中建立索引视图,以调整现有产品。如果您使用适当的列,那么优化器足够聪明,可以使用索引。
使用您的示例,您看起来好像创建了视图,但实际上并未在该视图上创建索引。
if object_id(N'mytable1') is not null
drop table mytable1
if object_id(N'mytable2') is not null
drop table mytable2
go
Create table mytable1 (ID int identity(1,1), Name1 nvarchar(100))
GO
Create table mytable2 (ID int identity(1,1), Name2 nvarchar(100))
GO
insert into mytable1 values ('steve')
insert into mytable1 values ('jack')
insert into mytable1 values ('mike')
insert into mytable1 values ('ralph')
insert into mytable1 values ('simon')
insert into mytable2 values ('smith')
insert into mytable2 values ('jackson')
insert into mytable2 values ('mikaelson')
insert into mytable2 values ('montalvo')
insert into mytable2 values ('singer')
go
if object_id(N'myview') is not null
drop view myview
go
Create view myview
with schemabinding
as
select a.id, a.name1, b.name2
from dbo.mytable1 a
join dbo.mytable2 b on a.Id = b.Id
GO
select a.name1, b.name2
from mytable1 a join mytable2 b on a.Id = b.Id
GO
由于此视图上没有索引,因此我们在基表上进行扫描:
但是一旦添加索引,优化器就可以使用它:
CREATE UNIQUE CLUSTERED INDEX [ix_cl_names] ON [myview]
(
[name1] ASC,
[name2] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
这适当地使用了视图:
我无法更改所有SQL脚本以从视图而不是表中进行选择。我想创建索引视图并强制SQL Server从它们而不是表中获取数据。
没有提示或其他方法可以强制SQL Server在查询中未引用索引视图时使用索引视图。
附加信息(来自Geoff Patterson)
还有一点是,虽然在这种情况下,优化器只能在Enterprise Edition中使用索引视图,但是NOEXPAND
如果您需要100%确定使用的是视图索引,则可以直接使用提示直接引用视图。如果您希望在标准版中使用它。
即使在企业版中,我也经常看到查询,在该版本中,优化器无法使用除非NOEXPAND
使用视图索引才能使用的事实。复杂查询更常见,但简单查询也可能发生。
保罗怀特(Paul White)是我阅读的更好的文章之一,探索了细微的差别NOEXPAND
; 除了使用视图索引之外,提示还可能影响诸如是否在索引视图上自动创建统计信息以及计划的基数估计之类的问题。
从Zane那里:作为一个附带说明,对索引视图要小心,就像它将添加到您的更新,插入和删除时间的任何其他索引一样。