Indizierte Ansicht in SQL Server

11

Ich habe eine Tabelle und eine indizierte Ansicht darauf wie

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

Nun, wenn ich die folgende Abfrage ausführe

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

Meine indizierte Ansicht wird nicht verwendet. Gibt es einen Hinweis (oder eine andere Möglichkeit), SQL Server zu zwingen, stattdessen die indizierte Ansicht zu verwenden?

Ich habe ein großes System und muss es optimieren. Ich kann nicht alle meine SQL-Skripte so ändern, dass sie anstelle von Tabellen aus der Ansicht ausgewählt werden. Ich möchte indizierte Ansichten erstellen und SQL Server zwingen, Daten von ihnen anstelle von Tabellen abzurufen.

Ich verwende SQL Server 2014 Enterprise Edition.

Artashes Khachatryan
quelle
Ich habe ein großes System und muss es optimieren. Ich kann nicht alle meine SQL-Skripte ändern, um sie anstelle von Tabellen aus der Ansicht auszuwählen. Ich möchte indizierte Ansichten erstellen und SQL Server zwingen, Daten von ihnen anstelle von Tabellen abzurufen.
Artashes Khachatryan

Antworten:

23

Ich erstelle ständig indizierte Ansichten in SQL Server, um vorhandene Produkte zu optimieren. Das Optimierungsprogramm ist intelligent genug, um den Index zu verwenden, wenn Sie die entsprechenden Spalten verwenden.

In Ihrem Beispiel sieht es so aus, als hätten Sie die Ansicht erstellt, aber keinen Index dafür erstellt.

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

Da diese Ansicht keinen Index enthält, scannen wir die Basistabellen: Geben Sie hier die Bildbeschreibung ein

Sobald wir jedoch einen Index hinzugefügt haben, kann der Optimierer ihn verwenden:

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

Dies nutzte die Ansicht angemessen: Geben Sie hier die Bildbeschreibung ein

Ich kann nicht alle meine SQL-Skripte so ändern, dass sie anstelle von Tabellen aus der Ansicht ausgewählt werden. Ich möchte indizierte Ansichten erstellen und SQL Server zwingen, Daten von ihnen anstelle von Tabellen abzurufen.

Es gibt keinen Hinweis oder eine andere Methode, um SQL Server zu zwingen, eine indizierte Ansicht zu verwenden, wenn in der Abfrage nicht auf sie verwiesen wird.

Zusätzliche Informationen (von Geoff Patterson )

Ein zusätzlicher Punkt ist, dass das Optimierungsprogramm in diesem Fall nur in der Enterprise Edition die indizierte Ansicht verwenden kann. Es kann jedoch sinnvoll sein, direkt auf die Ansicht mit dem NOEXPANDHinweis zu verweisen, wenn Sie 100% sicher sein müssen, ob der Ansichtsindex verwendet wird oder wenn Sie jemals möchten, dass es in der Standard Edition verwendet wird.

Ich habe selbst in Enterprise Edition häufig Abfragen gesehen, bei denen das Optimierungsprogramm nicht erkennt, dass der Ansichtsindex verwendet werden kann, sofern er nicht NOEXPANDverwendet wird. Es ist häufiger bei komplexen Abfragen, kann aber auch bei einfachen Abfragen auftreten.

Paul White hat einen der besseren Artikel, in denen ich die Nuancen von untersucht habe NOEXPAND. Über die reine Verwendung des Ansichtsindex hinaus kann sich der Hinweis auch auf die automatische Erstellung von Statistiken für die indizierte Ansicht und die Kardinalitätsschätzungen für den Plan auswirken.

Und von Zane : Seien Sie als Randnotiz vorsichtig mit indizierten Ansichten wie mit jedem anderen Index, der zu Ihren Aktualisierungs-, Einfüge- und Löschzeiten hinzugefügt wird.

beeks
quelle
-5

Wenn Sie Ihren Anwendungscode nicht in neue Objektnamen ändern können, können Sie Ihren Anwendungsbenutzer möglicherweise so ändern, dass er ein neues Standardschema verwendet und die indizierten Ansichten in einem anderen Schema mit denselben Objektnamen erstellt. Zum Beispiel:

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

Dies funktioniert natürlich nur, wenn Sie die Schemanamen im Anwendungscode nicht verwendet haben.

Wenn ja, können Sie versuchen, alle Objekte in ein neues Schema zu verschieben und stattdessen die Ansichten in das alte Schema einzuführen.

Magier
quelle