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.
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 : -
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:
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.