Vue indexée dans SQL Server


11

J'ai une table et une vue indexée dessus 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. Existe-t-il un indice (ou autre moyen) pour forcer SQL Server à utiliser la vue indexée à la place?

J'ai un gros système et je dois l'optimiser. Je ne peux pas modifier tous mes scripts SQL pour sélectionner dans la vue au lieu des tables. Je souhaite créer des vues indexées et forcer SQL Server à obtenir des données à leur place au lieu de tables.

J'utilise SQL Server 2014 Enterprise Edition.


J'ai un gros système et je dois l'optimiser. Je ne peux pas changer tous mes scripts SQL pour sélectionner dans la vue au lieu des tables. Je veux créer des vues indexées et forcer le serveur SQL à obtenir des données à leur place au lieu de tables.
Artashes Khachatryan

Réponses:


23

Je crée des vues indexées dans SQL Server tout le temps pour régler les produits existants. L'optimiseur est suffisamment intelligent pour utiliser l'index si vous utilisez les colonnes appropriées.

En utilisant votre exemple, il semble que vous ayez créé la vue mais que vous n'ayez pas réellement créé d'index dessus.

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

Puisqu'il n'y a pas d'index sur cette vue, nous analysons les tables de base: entrez la description de l'image ici

Mais une fois que nous avons ajouté 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é la vue de manière appropriée: entrez la description de l'image ici

Je ne peux pas modifier tous mes scripts SQL pour sélectionner dans la vue au lieu des tables. Je souhaite créer des vues indexées et forcer SQL Server à obtenir des données à leur place au lieu de tables.

Il n'existe aucun indice ou autre méthode pour forcer SQL Server à utiliser une vue indexée lorsqu'elle n'est pas référencée dans la requête.

Informations supplémentaires (de Geoff Patterson )

Un point supplémentaire est que même si l'optimiseur peut, dans Enterprise Edition uniquement, utiliser la vue indexée dans ce cas, il peut être judicieux de référencer directement la vue à l'aide de l' NOEXPANDindice si vous devez être sûr à 100% de l'index de vue utilisé ou si vous souhaitez qu'il soit utilisé dans l'édition Standard.

J'ai souvent vu des requêtes même dans Enterprise Edition où l'optimiseur ne détecte pas le fait que l'index de vue peut être utilisé à moins qu'il ne NOEXPANDsoit utilisé. C'est plus courant avec les requêtes complexes, mais cela peut aussi arriver avec des requêtes simples.

Paul White a l'un des meilleurs articles que j'ai lus en explorant les nuances de NOEXPAND; au-delà de l'utilisation de l'index de vue, l'indice peut également avoir un impact sur la création automatique de statistiques sur la vue indexée et les estimations de cardinalité du plan.

Et de Zane : En remarque, soyez prudent avec les vues indexées comme comme tout autre index qu'il ajoutera à vos heures de mise à jour, d'insertion et de suppression.


-5

Si vous ne pouvez pas changer votre code d'application en nouveaux noms d'objet, vous pouvez peut-être changer l'utilisateur de votre application pour utiliser un nouveau schéma par défaut et créer les vues indexées dans un autre schéma en utilisant les mêmes noms d'objet? Par exemple:

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

Bien sûr, cela ne fonctionnera que si vous n'avez pas utilisé les noms de schéma dans le code d'application.

Si c'est le cas, vous pouvez essayer de déplacer tous les objets vers un nouveau schéma et d'introduire les vues dans l'ancien schéma à la place.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.