(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

DP-900: entender e usar índices em Azure SQL Database

João Barros 02 de August de 2026 6 min de leitura

Vou ensinar a competência de compreender e aplicar índices em Azure SQL Database — um tema chave em "Dados relacionais no Azure" do DP-900. Saber como os índices funcionam importa tanto para responder às perguntas conceptuais do exame como para optimizar consultas na prática. Aqui explico conceitos, dou exemplos concretos e mostro como validar o impacto de um índice no mundo real.

O que precisas de saber

Um índice é uma estrutura que acelera a leitura de dados, semelhante ao índice de um livro que aponta para páginas onde um tema aparece. Em bases de dados relacionais como Azure SQL Database, índices reduzem o número de páginas de disco ou blocos que o sistema tem de ler para satisfazer uma consulta. Em termos práticos, uma consulta que antes fazia 2 000 logical reads pode passar a fazer 20 reads quando um índice adequado é utilizado — uma redução de 99% no trabalho de leitura em alguns cenários.

Exemplo simples: uma tabela Customers(id, name, city). Se escreveres muitas consultas que filtram por city, criar um índice em city pode tornar essas consultas muito mais rápidas porque o motor procura no índice em vez de ler a tabela completa (full table scan). Se a tabela tem 1 milhão de linhas e cada página de disco contém 8 KB, um full scan pode requerer milhares de páginas lidas; um índice selectivo reduz esse número drasticamente.

Conceitos essenciais:

  • Clustered index: determina a ordem física das linhas na tabela. Uma tabela pode ter apenas um clustered index (ex.: PRIMARY KEY por defeito). Escolhe uma chave clustered que seja estreita, estável e única sempre que possível (por exemplo, um ID incremental).
  • Non-clustered index: estrutura separada que mantém apontadores para as linhas da tabela; podes ter vários por tabela. Podem incluir colunas adicionais (INCLUDE) para criar um covering index.
  • Covering index: um índice que contém todas as colunas necessárias para uma consulta, evitando acessos adicionais à tabela. Por exemplo, um índice em (customer_id) INCLUDE (order_date, total) cobre uma query que só retorna essas colunas.
  • Seletividade: medida de quão exclusiva é uma coluna. Colunas com alta seletividade (p.ex., > 10% de valores distintos num conjunto grande) beneficiam mais de um índice; colunas com baixa seletividade (p.ex., género com apenas M/F) raramente ajudam.
  • Overhead: índices aceleram leitura mas aumentam o custo nas operações de escrita (INSERT/UPDATE/DELETE) e consomem espaço. Como regra prática, cada índice non-clustered pode adicionar 20–50% ao custo de armazenamento dependendo das colunas incluídas.

Como funciona na prática

Aqui tens um passo-a-passo prático para criar e validar um índice em Azure SQL Database usando T-SQL. Supõe que tens uma tabela Sales(order_id INT, customer_id INT, sale_date DATE, amount DECIMAL(10,2)).

-- 1. Criar um non-clustered index na coluna sale_date
CREATE INDEX IX_Sales_SaleDate
ON Sales(sale_date);

-- 2. Ver plano de execução para uma query que filtra por sale_date
SET STATISTICS IO ON;
SET STATISTICS TIME ON;

SELECT order_id, amount
FROM Sales
WHERE sale_date = '2025-01-15';

-- 3. Remover o índice se não for útil
DROP INDEX IX_Sales_SaleDate ON Sales;

Passos a considerar para decidir criar um índice:

  1. Identificar consultas frequentes e colunas usadas em WHERE, JOIN, ORDER BY. Ferramentas em Azure como Query Performance Insight e Intelligent Insights ajudam a ver queries mais dispendiosas.
  2. Avaliar seletividade: se uma coluna tem muitos valores repetidos, o índice pode não ser útil. Ex.: se 90% das linhas têm status = 'Active', um índice em status terá pouco efeito.
  3. Testar com e sem índice usando planos de execução, STATISTICS IO/TIME e medir logical reads. Observa métricas como tempo de CPU e elapsed time; uma melhoria de 10–100x é comum em casos ideais.
  4. Monitorizar impacto nas escritas: índices aumentam latência de INSERT/UPDATE/DELETE. Em cargas de escrita intensiva, cada índice pode acrescentar 1–5% de overhead por operação, dependendo da complexidade.

Erros comuns

  • Indexar todas as colunas: criar demasiados índices (ou índices em colunas pouco seletivas) aumenta o overhead nas escritas e ocupa espaço desnecessário. Em ambientes OLTP, manter 3–6 índices por tabela é comum; >10 costuma ser problemático.
  • Ignorar planos de execução: criar índices sem analisar o plano pode não resolver o problema; o Query Optimizer escolhe se usa o índice. Um índice mal desenhado pode sequer ser utilizado.
  • Não manter estatísticas: estatísticas desactualizadas levam o Query Optimizer a escolhas subótimas; lembra-te de UPDATE STATISTICS ou de configurar auto_update_statistics. Em tabelas grandes, uma actualização de estatísticas pode melhorar dramaticamente os planos.
  • Esquecer manutenção: índices fragmentam-se com o tempo; procedimentos de manutenção (REORGANIZE ou REBUILD) devem ser planeados. Em tabelas activas, um REBUILD semanal ou mensal pode ser necessário, dependendo da fragmentação (p.ex., >30%).

Como praticar

Pratica em Azure SQL Database com uma base de dados de amostra (ex.: WideWorldImporters ou AdventureWorks) e experimenta:

  • Criar/descartar índices e comparar planos de execução. Observa logical_reads antes/depois e aponta números concretos (ex.: de 2 500 para 150 reads).
  • Medir STATISTICS IO/TIME antes e depois para quantificar ganhos em I/O e tempo de CPU.
  • Simular carga de escrita para observar overhead: usa scripts que façam milhares de INSERT/UPDATE para medir latência e throughput com e sem índice.

Nota: Azure SQL Database tem funcionalidades de tuning automático que sugerem e aplicam índices; revê sempre as sugestões e testa antes de aplicar em produção. Para preparares o DP-900 usa o Practice Assessment OFICIAL (gratuito) da Microsoft e a study guide oficial (gratuita). Estes recursos ajudam-te a verificar conhecimentos nas áreas medidas pelo exame sem recorrer a materiais proibidos.

Em resumo

  • Índices aceleram leituras; há clustered e non-clustered, cada um com trade-offs.
  • Escolhe colunas com alta seletividade e uso frequente em filtros/join/order by. Considera incluir colunas com INCLUDE para criar covering indexes.
  • Testa alterações com planos de execução e métricas (STATISTICS IO/TIME) e monitoriza o impacto nas escritas.
  • Evita excesso de índices, mantém estatísticas actualizadas e programa manutenção (REORGANIZE/REBUILD) para evitar fragmentação.