SQL Server中的索引视图


11

我有一张桌子和它的索引视图

Create table mytable1 (ID int identity(1,1), Name nvarchar(100))

Create table mytable2 (ID int identity(1,1), Name nvarchar(100))

Create view myview 
with schemabinding 
as 
   select a.name, b.name
   from mytable1 a 
   join mytable2 b on a.Id = b.Id

现在,如果我运行以下查询

select a.name, b.name
from mytable1 a 
join mytable2 b on a.Id = b.Id

它不使用我的索引视图。是否有任何暗示(或其他方式)来强制SQL Server使用索引视图?

我的系统很大,需要对其进行优化。我无法更改所有SQL脚本以从视图而不是表中进行选择。我想创建索引视图并强制SQL Server从它们而不是表中获取数据。

我正在使用SQL Server 2014企业版。


我的系统很大,需要对其进行优化。我不能更改我所有的SQL脚本以从视图而不是表中进行选择。我想创建索引视图,并强制sql server从它们而不是表中获取数据。
Artashes Khachatryan 2015年

Answers:


23

我一直在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那里:作为一个附带说明,对索引视图要小心,就像它将添加到您的更新,插入和删除时间的任何其他索引一样。


-5

如果无法将应用程序代码更改为新的对象名,也许可以更改应用程序用户以使用新的默认架构,并使用相同的对象名称在另一个架构中创建索引视图?例如:

create view iv.MyTest 
as 
 select Col1, Col2 from dbo.MyTest 

当然,这仅在您未在应用程序代码中使用架构名称的情况下才有效。

如果有的话,您可以尝试将所有对象移至新架构,并在旧架构中引入视图。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.