Widok indeksowany w SQL Server

11

Mam na nim tabelę i indeksowany widok

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

Teraz jeśli uruchomię następujące zapytanie

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

Nie używa mojego widoku indeksowanego. Czy jest jakaś wskazówka (lub inny sposób), aby zmusić SQL Server do korzystania z widoku indeksowanego?

Mam duży system i muszę go zoptymalizować. Nie mogę zmienić wszystkich moich skryptów SQL, aby wybierać z widoku zamiast tabel. Chcę utworzyć indeksowane widoki i zmusić program SQL Server do pobierania danych z nich zamiast tabel.

Korzystam z programu SQL Server 2014 Enterprise Edition.

Artash Khachatryan
źródło
Mam duży system i muszę go zoptymalizować. Nie mogę zmienić wszystkich moich skryptów SQL, aby wybierać z widoku zamiast tabel. Chcę utworzyć indeksowane widoki i zmusić serwer sql do pobierania danych z nich zamiast tabel.
Artash Khachatryan,

Odpowiedzi:

23

Cały czas buduję indeksowane widoki w SQL Server, aby dostroić istniejące produkty. Optymalizator jest wystarczająco inteligentny, aby użyć indeksu, jeśli korzystasz z odpowiednich kolumn.

Na twoim przykładzie wygląda to tak, jakbyś utworzył widok, ale tak naprawdę nie utworzyłeś dla niego indeksu.

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

Ponieważ w tym widoku nie ma indeksu, skanujemy tabele podstawowe: wprowadź opis zdjęcia tutaj

Ale gdy dodamy indeks, optymalizator może go użyć:

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

To odpowiednio wykorzystało widok: wprowadź opis zdjęcia tutaj

Nie mogę zmienić wszystkich moich skryptów SQL, aby wybierać z widoku zamiast tabel. Chcę utworzyć indeksowane widoki i zmusić program SQL Server do pobierania danych z nich zamiast tabel.

Nie ma podpowiedzi ani innej metody, która zmusiłaby SQL Server do korzystania z widoku indeksowanego, gdy nie jest przywoływany w zapytaniu.

Dodatkowe informacje (od Geoff Patterson )

Dodatkową kwestią jest to, że chociaż optymalizator może w tym przypadku używać tylko widoku indeksowanego, sensowne może być bezpośrednie odwołanie do widoku za pomocą NOEXPANDpodpowiedzi, jeśli chcesz mieć 100% pewności, że indeks widoku jest używany lub jeśli kiedykolwiek chcesz, aby był używany w wersji Standard.

Często widziałem zapytania nawet w wersji Enterprise Edition, w których optymalizator nie zauważa, że ​​indeks widoku może być używany, chyba że NOEXPANDjest używany. Jest to bardziej powszechne w przypadku złożonych zapytań, ale może się zdarzyć także w przypadku prostych zapytań.

Paul White ma jeden z lepszych artykułów , które czytałem, badając niuanse NOEXPAND; podpowiedź może nie tylko wpływać na użycie indeksu widoków, ale także wpływać na to, czy statystyki są tworzone automatycznie na widok indeksowany, a szacunki liczności dla planu.

I od Zane'a : na marginesie, uważaj na indeksowane widoki, tak jak każdy inny indeks, który doda do twojej aktualizacji, wstawiania i usuwania czasów.

pszczoły
źródło
-5

Jeśli nie możesz zmienić kodu aplikacji na nowe nazwy obiektów, być może możesz zmienić użytkownika aplikacji, aby używał nowego domyślnego schematu i tworzył indeksowane widoki w innym schemacie przy użyciu tych samych nazw obiektów? Na przykład:

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

Oczywiście zadziała to tylko wtedy, gdy nie użyjesz nazw schematów w kodzie aplikacji.

Jeśli tak, możesz spróbować przenieść wszystkie obiekty do nowego schematu i zamiast tego wprowadzić widoki do starego schematu.

Magier
źródło