Visualização indexada no SQL Server

11

Eu tenho uma tabela e uma exibição indexada nela 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

Agora, se eu executar a seguinte consulta

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

Ele não usa minha exibição indexada. Existe alguma dica (ou outra maneira) para forçar o SQL Server a usar a exibição indexada?

Eu tenho um grande sistema e preciso otimizá-lo. Não consigo alterar todos os meus scripts SQL para selecionar na exibição em vez de tabelas. Quero criar modos de exibição indexados e forçar o SQL Server a obter dados deles em vez de tabelas.

Estou usando o SQL Server 2014 Enterprise Edition.

Artashes Khachatryan
fonte
Eu tenho um grande sistema e preciso otimizá-lo. Não consigo alterar todos os meus scripts sql para selecionar na visualização em vez de tabelas. Eu quero criar modos de exibição indexados e forçar o servidor sql a obter dados deles em vez de tabelas.
Artbat Khachatryan

Respostas:

23

Eu construo modos de exibição indexados no SQL Server o tempo todo para ajustar os produtos existentes. O otimizador é inteligente o suficiente para usar o índice se você estiver utilizando as colunas apropriadas.

Usando seu exemplo, parece que você criou a visualização, mas na verdade não criou um índice.

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 não há índice nessa exibição, verificamos nas tabelas base: insira a descrição da imagem aqui

Mas depois que adicionamos um índice, o otimizador pode usá-lo:

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

Isso usou adequadamente a exibição: insira a descrição da imagem aqui

Não consigo alterar todos os meus scripts SQL para selecionar na exibição em vez de tabelas. Quero criar modos de exibição indexados e forçar o SQL Server a obter dados deles em vez de tabelas.

Não há dica ou outro método para forçar o SQL Server a usar uma exibição indexada quando ela não é referenciada na consulta.

Informações adicionais (de Geoff Patterson )

Um ponto extra é que, embora o otimizador possa, apenas no Enterprise Edition, usar a exibição indexada nesse caso, pode fazer sentido referenciar diretamente a exibição usando a NOEXPANDdica, se você precisar ter 100% de certeza do índice de exibição que está sendo usado ou se você quiser que ele seja usado na Standard Edition.

Frequentemente, tenho visto consultas, mesmo no Enterprise Edition, em que o otimizador não entende o fato de que o índice de exibição pode ser usado, a menos que NOEXPANDseja usado. É mais comum em consultas complexas, mas também pode ocorrer em consultas simples.

Paul White tem um dos melhores artigos que li explorando as nuances de NOEXPAND; além do uso do índice de exibição, a dica também pode afetar coisas como se as estatísticas são criadas automaticamente na exibição indexada e nas estimativas de cardinalidade do plano.

E do Zane : como uma observação lateral, tenha cuidado com as exibições indexadas, como qualquer outro índice que ele adicionará às horas de atualização, inserção e exclusão.

Beeks
fonte
-5

Se você não pode alterar o código do aplicativo para novos nomes de objeto, talvez seja possível alterar o usuário do aplicativo para usar um novo esquema padrão e criar as visualizações indexadas em outro esquema usando os mesmos nomes de objeto? Por exemplo:

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

Obviamente, isso funcionará apenas se você não tiver usado os nomes dos esquemas no código do aplicativo.

Se você tiver, tente mover todos os objetos para um novo esquema e, em vez disso, introduza as visualizações no esquema antigo.

Magier
fonte