Esta é uma tentativa de melhorar o trabalho de Max Vernon . Em sua solução, ele sugere usar 2 índices na exibição e um objeto de estatística.
O 1º índice é agrupado, o que é realmente necessário, pois, diferentemente de um índice não clusterizado em uma tabela, um erro será gerado se a criação de um índice não clusterizado na exibição for tentada sem primeiro ter um índice clusterizado.
O segundo índice é um índice não clusterizado, usado como o índice por trás da consulta. Na seção de comentários de sua resposta, perguntei o que aconteceria se um índice clusterizado fosse usado em vez de um índice não clusterizado.
A análise a seguir tenta responder a essa pergunta.
Estou usando exatamente o mesmo código, exceto que não estou criando um índice não clusterizado na exibição.
Também não estou criando um objeto de estatística. Se estiver acompanhando e usando o SSMS (SQL Server Management Studio) para inserir o código abaixo, você deve estar ciente de que poderá ver algumas linhas onduladas vermelhas - que parecem erros. Estes (provavelmente) não são erros, mas envolvem um problema com o intellisense.
Você pode desativar o intellisense ou simplesmente ignorar os erros e executar os comandos. Eles devem ser concluídos sem erros.
-- Create the test table that uses a computed column.
USE tempdb;
CREATE TABLE dbo.PersistedViewTest
(
PersistedViewTest_ID INT NOT NULL
CONSTRAINT PK_PersistedViewTest
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, SomeData VARCHAR(2000) NOT NULL
, TestComputedColumn AS (PersistedViewTest_ID - 1) PERSISTED
);
GO
-- Insert some test data into the table.
INSERT INTO dbo.PersistedViewTest (SomeData)
SELECT o.name + o1.name + o2.name
FROM sys.objects o
CROSS JOIN sys.objects o1
CROSS JOIN sys.objects o2;
GO
O seguinte plano de execução (sem exibição / exibição de índice) é produzido depois que a seguinte consulta é executada na tabela:
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest pv
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
Isso fornece uma linha de base para comparação. Observe que, após a consulta concluída, um objeto estatístico foi criado (_WA_Sys_00000003_1FCDBCEB). O objeto de estatísticas PK_PersistedViewTest foi criado quando o índice da tabela em cluster foi criado.
Em seguida, a visualização filtrada e o índice clusterizado nessa visualização são criados:
-- Create filtered view on the computed column.
CREATE VIEW dbo.PersistedViewTest_View
WITH SCHEMABINDING
AS
SELECT PersistedViewTest_ID, SomeData, TestComputedColumn
FROM dbo.PersistedViewTest
WHERE TestComputedColumn < CONVERT(INT, 27);
GO
-- Create unique clustered index to persist the values, including the computed column.
CREATE UNIQUE CLUSTERED INDEX IX_PersistedViewTest
ON dbo.PersistedViewTest_View(PersistedViewTest_ID);
GO
Agora, vamos tentar executar a consulta novamente, mas desta vez na visualização:
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest_View pv
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
O novo plano de execução é agora:
Se o novo plano deve ser acreditado, após a adição da visualização e do índice clusterizado nessa visualização, as estatísticas parecem indicar que o tempo necessário para executar a consulta agora dobrou. Além disso, observe que nenhum novo objeto de estatística foi criado para oferecer suporte ao novo índice após a execução da consulta, que é diferente da consulta na tabela.
O plano de consulta ainda sugere que a criação de um índice não clusterizado seria bastante útil para melhorar o desempenho da consulta. Então, isso significa que um índice não clusterizado deve ser adicionado à visualização antes que a melhoria de desempenho desejada possa ser obtida? Há uma última coisa a tentar. Modifique a consulta para usar a opção "WITH NOEXPAND":
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest_View pv WITH (NOEXPAND)
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
Isso resulta no seguinte plano de consulta:
Esse plano de execução é bastante semelhante ao produzido com o índice não clusterizado, fornecido na resposta de Max Vernon. Mas, este é feito com um índice a menos (não clusterizado) e um objeto a menos de estatística.
Acontece que a opção NOEXPAND deve ser usada com as versões expressa e padrão do SQL Server para fazer uso adequado de uma exibição indexada. Paul White tem um excelente artigo que expõe os benefícios do uso da opção NOEXPAND. Ele também recomenda que essa opção seja usada com a edição corporativa para garantir que a garantia de exclusividade fornecida pelos índices de exibição seja usada pelo otimizador.
A análise acima foi feita com a edição expressa do SQL Sever 2014. Também tentei com a edição do desenvolvedor do SQL Server 2016. A opção NOEXPAND não parece ser necessária com a edição de desenvolvimento para obter ganhos de desempenho, mas ainda é recomendada .
Há menos de 5 meses, a Microsoft disponibilizou as edições do desenvolvedor . A licença restringe o uso apenas ao desenvolvimento, o que significa que o banco de dados não pode ser usado em um ambiente de produção. Portanto, se você estiver procurando testar tabelas, criptografia, R etc. otimizadas para memória, não terá mais a desculpa da ausência de licença. Eu o instalei com sucesso no meu computador há alguns dias, ao lado do SQL Server 2014 Express, sem problemas.
WHERE (sintMarketID = 2 AND strType = 'CARD' AND strTier1 LIKE 'GG%')
entanto.