Vista indizada en SQL Server


11

Tengo una tabla y una vista indizada como

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

Ahora si ejecuto la siguiente consulta

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

No usa mi vista indizada. ¿Hay alguna pista (u otra forma) para obligar a SQL Server a usar la vista indizada?

Tengo un gran sistema y necesito optimizarlo. No puedo cambiar todos mis scripts SQL para seleccionar desde la vista en lugar de las tablas. Quiero crear vistas indexadas y forzar a SQL Server a obtener datos de ellas en lugar de tablas.

Estoy usando SQL Server 2014 Enterprise Edition.


Tengo un gran sistema y necesito optimizarlo. No puedo cambiar todos mis scripts sql para seleccionar de la vista en lugar de tablas. Quiero crear vistas indexadas y forzar al servidor sql a obtener datos de ellas en lugar de tablas.
Artashes Khachatryan

Respuestas:


23

Construyo vistas indexadas en SQL Server todo el tiempo para ajustar los productos existentes. El optimizador es lo suficientemente inteligente como para usar el índice si está utilizando las columnas apropiadas.

Usando su ejemplo, parece que creó la vista pero en realidad no creó un índice sobre ella.

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

Como no hay índice en esta vista, escaneamos las tablas base: ingrese la descripción de la imagen aquí

Pero una vez que agregamos un índice, el optimizador puede usarlo:

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

Esto usó apropiadamente la vista: ingrese la descripción de la imagen aquí

No puedo cambiar todos mis scripts SQL para seleccionar desde la vista en lugar de las tablas. Quiero crear vistas indexadas y forzar a SQL Server a obtener datos de ellas en lugar de tablas.

No hay ninguna sugerencia u otro método para obligar a SQL Server a usar una vista indizada cuando no se hace referencia en la consulta.

Información adicional (de Geoff Patterson )

Un punto adicional es que si bien el optimizador puede, solo en Enterprise Edition, usar la vista indexada en este caso, puede tener sentido hacer referencia directa a la vista usando la NOEXPANDsugerencia si necesita estar 100% seguro del índice de vista que se está utilizando o si alguna vez quieres que se use en Standard Edition.

Con frecuencia he visto consultas incluso en Enterprise Edition donde el optimizador no detecta el hecho de que el índice de vista se puede usar a menos que NOEXPANDse use. Es más común con consultas complejas, pero también puede ocurrir con consultas simples.

Paul White tiene uno de los mejores artículos que he leído explorando los matices de NOEXPAND; más allá del uso del índice de vista, la sugerencia también puede afectar cosas como si las estadísticas se crean automáticamente en la vista indexada y las estimaciones de cardinalidad para el plan.

Y de Zane : como nota al margen, tenga cuidado con las vistas indexadas como cualquier otro índice que agregará a sus tiempos de actualización, inserción y eliminación.


-5

Si no puede cambiar el código de su aplicación a nuevos nombres de objeto, ¿tal vez pueda cambiar el usuario de su aplicación para usar un nuevo esquema predeterminado y crear las vistas indexadas en otro esquema usando los mismos nombres de objeto? Por ejemplo:

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

Por supuesto, esto solo funcionará si no ha utilizado los nombres de esquema en el código de la aplicación.

Si es así, puede intentar mover todos los objetos a un nuevo esquema e introducir las vistas en el esquema anterior.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.