Индексированное представление в 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 Enterprise Edition.

Арташес Хачатрян
источник
У меня большая система, и мне нужно ее оптимизировать. Я не могу изменить все свои сценарии sql, чтобы выбрать из представления вместо таблиц. Я хочу создать индексированные представления и заставить сервер SQL получать данные из них вместо таблиц.
Арташес Хачатрян

Ответы:

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 использовать индексированное представление, если на него нет ссылки в запросе.

Дополнительная информация (от Джеффа Паттерсона )

Еще одно замечание: в этом случае оптимизатор может использовать только индексированное представление Enterprise Edition, в этом случае имеет смысл напрямую ссылаться на представление, используя NOEXPANDподсказку, если вам нужно быть на 100% уверенным в использовании индекса представления или если вы когда-нибудь захотите использовать его в стандартной версии.

Я часто видел запросы даже в Enterprise Edition, где оптимизатор не улавливал тот факт, что индекс представления может использоваться, если NOEXPANDне используется. Это чаще встречается в сложных запросах, но может происходить и в простых запросах.

У Пола Уайта есть одна из лучших статей, которые я читал, исследуя нюансы NOEXPAND; помимо простого использования индекса представления, подсказка также может влиять на такие вещи, как то, автоматически ли создается статистика в индексированном представлении, и оценки количества элементов для плана.

И от Зейна : Как примечание, будьте осторожны с индексированными представлениями, как и с любым другим индексом, который он добавит к вашему времени обновления, вставки и удаления.

beeks
источник
-5

Если вы не можете изменить код приложения на новые имена объектов, возможно, вы можете изменить пользователя приложения, чтобы использовать новую схему по умолчанию и создавать индексированные представления в другой схеме, используя те же имена объектов? Например:

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

Конечно, это будет работать, только если вы не использовали имена схем в коде приложения.

Если у вас есть, вы можете попытаться переместить все объекты в новую схему и вместо этого ввести представления в старой схеме.

Magier
источник