Criei uma visão materializada no SQL Server, mas ao selecionar a partir dela obtenho os mesmos desempenhos e o mesmo plano de execução do que quando seleciono da mesma consulta não "materializada".
A visão é simples:
CREATE VIEW TestView WITH SCHEMABINDING
AS
SELECT TAB_A.C1, TAB_A.C2, TAB_A.C3
FROM TAB1
INNER JOIN TAB2 ON TAB1.C2 = TAB2.C2
INNER JOIN TAB3 ON TAB2.C1 = TAB3.C1;
CREATE UNIQUE CLUSTERED INDEX IX_TestView
ON TestView(C1, C2, C3);
Agora, quando eu faço algo como
SELECT C1 FROM TestView
Eu esperaria ver no plano apenas um acesso à visão e nada mais, em vez disso, ele acessa as tabelas subjacentes como se a visão nem existisse. Eu recebo exatamente o mesmo plano e o mesmo tempo de execução também.
O que estou fazendo errado? Se o SQL Server não puder "materializar" a exibição, esperaria pelo menos obter um erro ao criá-la.
Como @sp_BlitzErik observou nos comentários, você precisa usar a
WITH (NOEXPAND)
dica, assim:Quando o SQL Server lê sua consulta e substitui o nome da exibição pela definição da exibição, isso é conhecido como "expandir" a exibição, portanto, com
NOEXPAND
, você diz especificamente ao SQL Server para não expandir a exibição, mas usar o índice que está lá .Por outro lado, se não houver índice (como se alguém o fizer
ALTER VIEW
!), a consulta falhará se você usarWITH NOEXPAND
.