web-dev-qa-db-fra.com

Vue indexée dans SQL Server

J'ai une table et une vue indexée sur elle comme

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

Maintenant si j'exécute la requête suivante

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

Il n'utilise pas ma vue indexée. Y a-t-il un indice (ou une autre manière) pour forcer SQL Server à utiliser une vue indexée à la place?

J'ai un grand système et j'ai besoin de l'optimiser. Je ne peux pas changer tous mes scripts SQL pour sélectionner la vue au lieu de tables. Je souhaite créer des vues indexées et force SQL Server pour obtenir des données d'eux au lieu de tables.

J'utilise SQL Server 2014 Enterprise Edition.

11

Je construise des vues indexées dans SQL Server tout le temps d'accorder des produits existants. L'optimiseur est suffisamment intelligente pour utiliser l'index si vous utilisez les colonnes appropriées.

En utilisant votre exemple, on dirait que vous avez créé la vue mais que vous n'avez pas créé d'index sur celui-ci.

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

Comme il n'y a pas d'index sur cette vue, nous numérisons sur les tables de base : -enter image description here

Mais une fois que nous ajoutons un index, l'optimiseur peut l'utiliser:

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

Cela a utilisé correctement la vue: enter image description here

Je ne peux pas changer tous mes scripts SQL pour sélectionner la vue au lieu de tables. Je souhaite créer des vues indexées et force SQL Server pour obtenir des données d'eux au lieu de tables.

Il n'y a pas d'indice ni d'autre méthode pour forcer SQL Server à utiliser une vue indexée lorsqu'il n'est pas référencé dans la requête.

Informations supplémentaires (à partir de Geoff Patterson )

Un point supplémentaire est que, tandis que l'optimiseur peut seulement, dans l'édition d'entreprise, utilisez la vue indexée dans ce cas, il peut être logique de référencer directement la vue à l'aide de l'indice NOEXPAND si vous devez être sûr de 100% de L'indice d'affichage utilisé ou si vous souhaitez que cela soit utilisé dans l'édition standard.

J'ai fréquemment vu des requêtes, même dans l'édition d'Enterprise où l'optimiseur ne prend pas le fait que l'index de vue peut être utilisé à moins que NOEXPAND est utilisé. Il est plus commun avec des requêtes complexes, mais peut également se produire avec des requêtes simples.

Paul White a l'un des meilleurs articles J'ai lu explorer les nuances de NOEXPAND; Au-delà de l'utilisation de l'indice d'affichage, l'indice peut également avoir une incidence sur les choses comme si les statistiques sont automatiquement créées sur la vue indexée et les estimations de cardinalité pour le plan.

Et à partir de - zane : En tant que note latérale, soyez prudent avec des vues indexées, comme tout autre index, il ajoutera à votre mise à jour, à insérer et à supprimer des temps.

23
beeks