Introdução aos índices SQL
Lição 10.4 · Tempo de leitura: ~10 min · Tarefas para praticar ↓
Esta lição introduz índices SQL e seu papel na performance de consultas. Você vai aprender o que é um índice, como ele ajuda a encontrar dados mais rápido e por que, em alguns casos, pode deixar operações de modificação mais lentas. Vamos ver exemplos básicos de criação e verificação de índices usando tabelas Sakila. Ao final da lição, você conseguirá usar índices de forma mais consciente para acelerar consultas reais.
Na lição anterior, aprendemos a ler plano de execução com EXPLAIN e encontrar gargalos. O próximo passo lógico é entender o principal mecanismo de aceleração de busca: índices.
Índices estão diretamente ligados a como o SGBD procura linhas. Sem índice, o servidor frequentemente varre a tabela inteira. Com um índice adequado, ele pode chegar aos dados relevantes muito mais rápido.
O que é um índice
Um índice SQL é uma estrutura de dados adicional que ajuda o SGBD a encontrar linhas mais rapidamente por valores de coluna.
Uma analogia simples é o índice de um livro. Em vez de ler todas as páginas, você usa o índice e vai direto para a seção desejada.
Em bancos relacionais, índices B-tree são os mais comuns e funcionam bem para:
- buscas exatas (
=); - intervalos (
>,<,BETWEEN); - ordenação (
ORDER BY) em colunas indexadas.
Como o índice afeta a performance
Acelera leitura (SELECT)
Quando a condição WHERE usa uma coluna indexada, o SGBD pode localizar linhas sem varrer a tabela inteira.
Pode deixar escrita mais lenta (INSERT, UPDATE, DELETE)
Todo índice precisa ser mantido atualizado. Quando os dados mudam, o SGBD atualiza a tabela e os índices relacionados.
Ocupa espaço adicional
Índices são armazenados separadamente e consomem disco. Criar índice em todas as colunas normalmente é uma estratégia ruim.
Sintaxe básica
Criação de índice simples:
CREATE INDEX idx_customer_last_name
ON customer (last_name);
Remoção de índice (sintaxe varia por SGBD):
DROP INDEX idx_customer_last_name ON customer;
Observação: no PostgreSQL, a forma é DROP INDEX index_name; sem nome de tabela.
Exemplo 1: acelerando filtro em uma coluna
Suponha que buscamos clientes por sobrenome com frequência:
SELECT
customer_id,
first_name,
last_name
FROM customer
WHERE last_name = 'SMITH';
Sem índice em last_name, o SGBD pode fazer varredura completa de customer. Depois de criar o índice, o acesso costuma mudar para um tipo mais eficiente.
Validação com EXPLAIN:
EXPLAIN
SELECT
customer_id,
first_name,
last_name
FROM customer
WHERE last_name = 'SMITH';
Resultado: no plano de execução, você deve ver uso de índice (key/possible_keys no MySQL ou Index Scan no PostgreSQL).
Exemplo 2: índice composto
Se as consultas filtram com frequência por dois campos juntos, um índice composto é útil.
CREATE INDEX idx_payment_customer_date
ON payment (customer_id, payment_date);
Uma consulta que combina bem com esse índice:
SELECT
payment_id,
customer_id,
amount,
payment_date
FROM payment
WHERE customer_id = 15
AND payment_date >= '2005-07-01'
ORDER BY payment_date;
Observação: a ordem das colunas no índice composto é importante. Em muitos casos, coloque primeiro o campo mais usado em filtro.
Quando um índice pode não ser usado
Mesmo com índice criado, o otimizador pode ignorá-lo. Causas comuns:
- função sobre coluna indexada no
WHERE(YEAR(payment_date)); - busca com
%no início (LIKE '%abc'); - baixa seletividade da coluna;
- ordem inadequada de colunas no índice composto.
Exemplo de condição que frequentemente impede uso de índice:
SELECT
payment_id,
payment_date
FROM payment
WHERE YEAR(payment_date) = 2005;
Versão mais amigável para índice:
SELECT
payment_id,
payment_date
FROM payment
WHERE payment_date >= '2005-01-01'
AND payment_date < '2006-01-01';
Recomendações práticas
- Adicione índices para consultas frequentes reais, não "por garantia".
- Comece por colunas usadas em
WHERE,JOINeORDER BY. - Depois de criar índice, compare o plano com
EXPLAIN. - Mantenha equilíbrio: índices demais podem piorar operações de escrita.
Principais conclusões desta lição:
- Índice é uma estrutura que acelera busca de linhas.
- Índices geralmente aceleram
SELECT, mas podem deixarINSERT,UPDATEeDELETEmais lentos. - Índices simples e compostos atendem padrões de filtro diferentes.
- A ordem das colunas em índice composto é crítica.
EXPLAINajuda a confirmar se o SGBD usa o índice criado.
Perguntas Frequentes
A chave primária cria um índice automaticamente?
Sim. No MySQL, no PostgreSQL e no SQL Server, as restrições PRIMARY KEY e UNIQUE criam um índice automaticamente. Com chaves estrangeiras é diferente: o MySQL (InnoDB) cria um índice na coluna da chave estrangeira se não houver nenhum, enquanto o PostgreSQL não cria, e você precisa adicioná-lo.
Quantos índices uma tabela deve ter?
Não existe um número fixo. Cada índice acelera as consultas que combinam com ele, mas deixa INSERT, UPDATE e DELETE mais lentos e ocupa espaço em disco. Indexe as colunas dos WHERE, JOIN e ORDER BY frequentes e remova índices não usados ou duplicados: um índice em (customer_id) é redundante ao lado de um em (customer_id, payment_date).
Como ver os índices de uma tabela?
No MySQL, execute SHOW INDEX FROM customer;. No PostgreSQL, use \d customer no psql ou consulte a view do sistema: SELECT indexname, indexdef FROM pg_indexes WHERE tablename = 'customer';.
Perguntas de entrevista
O que é um índice SQL e por que ele é útil?
Índice é uma estrutura de dados adicional que acelera busca de linhas por valor de coluna. Ele é útil porque reduz tempo de leitura e volume de dados varridos.
Por que um índice pode acelerar SELECT e ao mesmo tempo deixar INSERT mais lento?
Em leitura, o índice ajuda a localizar linhas rapidamente. Em escrita, o SGBD precisa atualizar dados da tabela e estruturas de índice, o que aumenta o trabalho.
Como verificar se um índice está sendo realmente usado?
Execute EXPLAIN na consulta e analise o plano: tipo de acesso, índice escolhido e estimativa de linhas.