Introdução aos índices SQL
Lição 10.3 · 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, vimos como escrever consultas que fazem menos trabalho desnecessário. 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: colocado antes da consulta, ele faz o banco de dados mostrar o plano de execução em vez do resultado, incluindo o índice usado:
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.