Como criar e usar Indexed Views em SQL Server: passo a passo
Explica-se como criar e usar Indexed Views em SQL Server para acelerar consultas com agregações e juntar dados pré-calculados. Esta técnica é útil em cenários de leitura intensiva em que reduzir o custo de CPU e I/O melhora a capacidade de resposta das consultas.
Pré-requisitos
- SQL Server (2016+ recomendado) com permissões para criar índices e views.
- SQL Server Management Studio (SSMS) ou outra interface T-SQL.
- Conhecimentos básicos de T-SQL: CREATE VIEW, CREATE INDEX, SELECT.
Passo 1: Entender quando usar Indexed Views
Indexed Views armazenam os resultados de uma view materializada com um índice clusterizado. São úteis para consultas com agregações ou junções repetidas, reduzindo o tempo de execução. Não são adequadas quando existem muitas escritas na base de dados porque o custo de manutenção do índice aumenta.
Passo 2: Criar uma tabela de exemplo
Comece por criar uma tabela simples de vendas. O exemplo é mínimo e funcional para testar Indexed Views.
CREATE TABLE Sales (
SalesID INT IDENTITY PRIMARY KEY,
ProductID INT NOT NULL,
SaleDate DATE NOT NULL,
Quantity INT NOT NULL,
Amount DECIMAL(10,2) NOT NULL
);
-- Inserir alguns dados de teste
INSERT INTO Sales (ProductID, SaleDate, Quantity, Amount)
VALUES
(1, '2026-01-01', 2, 19.98),
(1, '2026-01-02', 1, 9.99),
(2, '2026-01-01', 5, 49.95);
Passo 3: Regras e limitações a conhecer
Antes de criar a Indexed View, cumpra regras: a view tem de ser schemabound, não pode usar funções não determinísticas nem OUTER JOIN, e todas as colunas referidas devem ser determinísticas. O índice clusterizado exige que a view seja materializada.
Passo 4: Criar a view com SCHEMABINDING
A vista deve usar WITH SCHEMABINDING para evitar alterações nas tabelas subjacentes que invalidem a view.
CREATE VIEW dbo.vw_SalesByProduct
WITH SCHEMABINDING
AS
SELECT
ProductID,
COUNT_BIG(*) AS SalesCount,
SUM(Quantity) AS TotalQuantity,
SUM(Amount) AS TotalAmount
FROM dbo.Sales
GROUP BY ProductID;
Passo 5: Criar o índice clusterizado na view (materializar)
Depois de criada a view, materialize-a com um índice clusterizado. O indexado torna a vista física e acelera as consultas que a utilizam.
CREATE UNIQUE CLUSTERED INDEX IX_vw_SalesByProduct_ProductID
ON dbo.vw_SalesByProduct (ProductID);
Passo 6: Consultar usando a Indexed View
Execute consultas que beneficiem do índice. O Query Optimizer pode usar automaticamente a view materializada mesmo que a consulta leia apenas a tabela base, mas é possível forçar o uso com a hint NOEXPAND em edições Standard/Enterprise conforme necessário.
-- Consulta que usa a view diretamente
SELECT ProductID, TotalQuantity, TotalAmount
FROM dbo.vw_SalesByProduct
WHERE ProductID = 1;
-- Forçar uso da view (em edições onde aplica)
SELECT ProductID, TotalQuantity
FROM dbo.vw_SalesByProduct WITH (NOEXPAND)
WHERE ProductID = 1;
Passo 7: Gerir manutenção e atualizações
Quando inserir, actualizar ou apagar linhas na tabela Sales, o SQL Server actualiza automaticamente a Indexed View. Este custo adicional deve ser monitorizado. Para cargas de escrita intensivas, pondere alternativas como ETL periódico para tabelas agregadas.
-- Exemplo de inserção que actualiza a Indexed View automaticamente
INSERT INTO Sales (ProductID, SaleDate, Quantity, Amount)
VALUES (1, GETDATE(), 3, 29.97);
Verificar o resultado
Confirme que a view está materializada e a ser utilizada: verifique a existência do índice e analise planos de execução. Use sys.indexes e o plano estimado/executado no SSMS.
-- Verificar índice na view
SELECT object_name(object_id) AS ObjectName, name AS IndexName, type_desc
FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.vw_SalesByProduct');
-- Obter plano estimado no SSMS para ver se usa a view/index
-- (Use a opção "Display Estimated Execution Plan")
Conclusão
Indexed Views em SQL Server são uma solução prática para acelerar consultas agregadas e repetitivas, especialmente em cenários de leitura intensiva. Experimente com dados reais, monitorize o custo de manutenção em cenários de escrita e considere índices adicionais ou ETL se a carga de escrita for elevada. Dica: teste com e sem WITH (NOEXPAND) para perceber o impacto no plano — qual o resultado nos teus testes?