Індексований вигляд у 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 використовувати індексований вигляд, коли на нього не посилається запит.

Додаткова інформація (від Geoff Patterson )

Одним із додаткових моментів є те, що, хоча оптимізатор може лише в Enterprise Edition використовувати в цьому випадку індексований вигляд, може мати сенс безпосередньо посилатися на подання, використовуючи NOEXPANDпідказку, якщо вам потрібно бути 100% впевненим у використанні індексу перегляду або якщо ви хочете, щоб він використовувався в стандартній версії.

Я часто бачив запити навіть у Enterprise Edition, де оптимізатор не підбирає той факт, що індекс перегляду може бути використаний, якщо NOEXPANDне використовується. Він частіше зустрічається зі складними запитами, але може траплятися і з простими запитами.

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

І від Zane : Як бічна примітка, будьте обережні з індексованими поданнями, як і будь-який інший індекс, який він додасть до ваших оновлень, вставки та видалення разів.


-5

Якщо ви не можете змінити код свого додатка на нові імена об’єктів, можливо, ви можете змінити користувача своєї програми на використання нової схеми за замовчуванням та створення індексованих представлень в іншій схемі, з однаковими назвами об'єктів? Наприклад:

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

Звичайно, це спрацює лише в тому випадку, якщо ви не використовували назви схем у коді програми.

Якщо у вас є, ви можете спробувати перемістити всі об'єкти до нової схеми і замість цього ввести представлення у стару схему.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.