DevPath · Aprenda a programar ESPTEN

Desempenho, transações e NoSQL

Índices: acelerar as buscas

O problema: a varredura de tabela completa

Quando você executa uma consulta com um filtro, por padrão o banco de dados faz uma varredura de tabela completa (full table scan): percorre todas as linhas uma a uma para verificar quais cumprem a condição.

SELECT * FROM pedidos WHERE cliente_id = 11;

Com 10 linhas não dá para notar. Com 10 milhões de linhas, percorrê-las todas a cada consulta é inviável. O custo cresce de forma linear: O(n).

A solução: um índice

Um índice é uma estrutura de dados auxiliar, ordenada, que o banco de dados mantém à parte da tabela. Funciona como o índice alfabético de um livro: em vez de ler o livro inteiro procurando uma palavra, você vai ao índice (ordenado) e salta direto para a página.

Internamente, a maioria dos motores (SQLite, PostgreSQL, MySQL) usa uma árvore B+ (B-tree): uma árvore balanceada onde cada nível divide o espaço de busca. Buscar um valor custa O(log n): com 10 milhões de linhas, em vez de 10.000.000 de comparações, bastam ~24.

Linhas (n) Varredura O(n) Índice O(log n)
1.000 1.000 ~10
1.000.000 1.000.000 ~20
1.000.000.000 1.000.000.000 ~30

Criar um índice

CREATE INDEX idx_pedidos_cliente ON pedidos (cliente_id);

A partir desse momento, as consultas que filtram (WHERE), ordenam (ORDER BY) ou agrupam por cliente_id podem usar o índice. A chave primária (PRIMARY KEY) é indexada automaticamente; por isso buscar por id já é rápido sem fazer nada.

Um índice pode abranger várias colunas (índice composto). A ordem importa: idx (pais, estado) serve para filtrar por pais ou por pais AND estado, mas não para filtrar apenas por estado.

CREATE INDEX idx_pedidos_pais_estado ON pedidos (pais, estado);

Quando criar um índice?

Crie índices nas colunas que aparecem com frequência em:

O custo: não são de graça

Os índices não são mágica gratuita. Eles têm um preço:

Regra prática: indexe o que você consulta muito, não tudo. Um índice não usado é puro custo sem benefício.

Ver o que o planejador faz: EXPLAIN QUERY PLAN

Para saber se uma consulta usa um índice ou varre a tabela, anteponha EXPLAIN QUERY PLAN (sintaxe do SQLite; no PostgreSQL/MySQL é EXPLAIN):

EXPLAIN QUERY PLAN
SELECT * FROM pedidos WHERE cliente_id = 11;

É a ferramenta nº 1 para diagnosticar consultas lentas: primeiro meça, não adivinhe.

Exemplos

Criar um índice e consultar usando-o

CREATE INDEX idx_pedidos_cliente ON pedidos (cliente_id);

SELECT id, total
FROM pedidos
WHERE cliente_id = 11
ORDER BY id;

Diagnosticar o plano de execução

EXPLAIN QUERY PLAN
SELECT * FROM pedidos WHERE cliente_id = 11;
Coloque isto em prática

O DevPath é um curso prático: aqui você lê a teoria; no app você a coloca em prática com exercícios que rodam de verdade, offline.

Comece grátis no app →
Transações e ACID →