SQL Server 中的索引视图

Art*_*yan 11 sql-server materialized-view sql-server-2014

我有一张桌子和一个索引视图,就像

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
Run Code Online (Sandbox Code Playgroud)

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

select a.name, b.name
from mytable1 a 
join mytable2 b on a.Id = b.Id
Run Code Online (Sandbox Code Playgroud)

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

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

我使用的是 SQL Server 2014 企业版。

bee*_*eks 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
Run Code Online (Sandbox Code Playgroud)

由于此视图上没有索引,我们在基表上进行扫描: 在此处输入图片说明

但是一旦我们添加了索引,优化器就可以使用它:

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
Run Code Online (Sandbox Code Playgroud)

这适当地使用了视图: 在此处输入图片说明

我无法更改所有 SQL 脚本以从视图而不是表中进行选择。我想创建索引视图并强制 SQL Server 从它们而不是表中获取数据。

没有提示或其他方法可以强制 SQL Server 在查询中未引用索引视图时使用索引视图。

附加信息(来自Geoff Patterson

额外的一点是,虽然优化器只能在企业版中在这种情况下使用索引视图,但NOEXPAND如果您需要 100% 确定正在使用的视图索引,则使用提示直接引用视图可能是有意义的,或者如果您希望在标准版中使用它。

我经常看到甚至在企业版中的查询,其中优化器不会发现视图索引可以使用的事实,除非NOEXPAND使用。这在复杂查询中更为常见,但在简单查询中也可能发生。

Paul White 有一篇我读过的更好的文章,探讨了NOEXPAND; 除了视图索引的使用之外,提示还可以影响诸如是否在索引视图上自动创建统计信息和计划的基数估计之类的事情。

来自Zane:作为旁注,请注意索引视图,就像任何其他索引一样,它会添加到您的更新、插入和删除时间。


Mag*_*ier -5

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

create view iv.MyTest 
as 
 select Col1, Col2 from dbo.MyTest 
Run Code Online (Sandbox Code Playgroud)

当然,只有当您没有在应用程序代码中使用模式名称时,这才有效。

如果有,您可以尝试将所有对象移动到新模式并在旧模式中引入视图。