A busca de um documento em uma tabela com milhões de vendas pode levar vários segundos ou poucos milésimos de segundo, conforme o caminho que o servidor tem para chegar à linha. O índice é esse caminho. Entender o que o índice faz, e quanto ele custa, ajuda a investigar uma lentidão sem confundi-la com um defeito do banco.
O índice como caminho até a linha
Sem um índice adequado, o servidor encontra o documento 4521 lendo todas as linhas da tabela e conferindo uma por uma. Esse caminho se chama varredura completa da tabela. Com um índice na coluna numero_documento, o servidor procura o valor em uma estrutura ordenada e vai direto às linhas que o contêm.
O índice é uma estrutura mantida pelo banco, separada das linhas, com os valores de uma ou mais colunas em ordem e, para cada valor, a indicação da linha correspondente. Nos índices comuns do MySQL, essa estrutura é uma árvore, chamada de B-tree, que encontra um valor entre milhões de entradas com poucas leituras.
O que o índice acelera
- Busca por valor:
WHERE numero_documento = 4521encontra as linhas sem ler a tabela inteira. - Busca por faixa:
WHERE data_venda >= '2026-10-01' AND data_venda < '2026-11-01'percorre apenas o trecho do índice entre as duas datas. - Ordenação:
ORDER BY codigo LIMIT 20pode ler as primeiras linhas na ordem do índice, sem ordenar a tabela inteira. - Junção: um índice na coluna
venda_idda tabelaitens_vendaencontra os itens de cada venda sem percorrer todos os itens.
O índice com várias colunas
Um índice pode reunir várias colunas, e a ordem delas importa. Um índice sobre caixa e data_venda, nessa ordem, organiza as linhas primeiro por caixa e, dentro de cada caixa, por data, como o resultado de ORDER BY caixa, data_venda. Esse índice ajuda as buscas que começam pelo caixa:
WHERE caixa = 'CX01': usa a primeira coluna do índice;WHERE caixa = 'CX01' AND data_venda >= '2026-10-07': usa as duas colunas.
Uma condição apenas na data não aproveita o índice da mesma forma, porque as datas estão em ordem só dentro de cada caixa. Essa regra se chama prefixo à esquerda: o índice composto serve às buscas que usam as suas primeiras colunas.
Quando o índice não ajuda
O índice guarda os valores da coluna como estão gravados. Uma condição que transforma a coluna antes de comparar impede a busca direta no índice:
WHERE DATE(data_venda) = '2026-10-07': aplica uma função à coluna em cada linha;WHERE codigo = 123, em uma coluna de texto: converte o texto de cada linha em número;WHERE descricao LIKE '%DIPIRONA%': procura o texto em qualquer posição, e a ordem do índice não ajuda a localizá-lo.
Nos dois primeiros casos, a mesma busca pode ser escrita de outra forma. A data vira uma faixa, com maior ou igual e menor que, e o código vai entre aspas.
Uma busca que atinge grande parte da tabela também dispensa o índice. Um índice na coluna situacao, que tem apenas os valores F e C, ajuda pouco na busca das vendas finalizadas, porque quase todas as linhas atendem à condição, e ler a tabela inteira sai mais barato do que consultar o índice para cada linha.
Quem escolhe o caminho
O otimizador é a parte do MySQL que escolhe o caminho de cada consulta. Ele considera os índices disponíveis e estimativas sobre os dados, chamadas de estatísticas. Por isso, a existência de um índice não garante o seu uso, e o comando EXPLAIN, escrito antes de um SELECT, mostra o caminho escolhido.
O custo dos índices
Cada índice ocupa espaço em disco e na memória do servidor. Cada inclusão, alteração ou exclusão de linha atualiza também os índices afetados. Uma tabela com muitos índices fica mais lenta para gravar, e o custo aparece em operações com muitas gravações, como o fechamento de uma venda com muitos itens. Por isso, os índices acompanham as buscas e as ordens que o sistema realmente usa, e não a quantidade de colunas da tabela.
A lentidão não prova defeito
Uma consulta que era rápida e ficou lenta pode ter perdido um índice depois de uma recriação da tabela, mudado de caminho por causa das estatísticas, passado a examinar mais dados ou ficado à espera de outra conexão. A lentidão indica onde começar a investigação, mas não prova que um índice está danificado.
No suporte
Diante de uma consulta lenta, convém guardar o SQL exato e comparar as condições e a ordem com os índices da tabela. Uma condição com função, com conversão de tipo ou com curinga no início explica muitas lentidões sem nenhum defeito no banco.
Para guardar
- O índice é uma estrutura ordenada que leva o servidor direto às linhas, sem a varredura completa da tabela.
- O índice acelera buscas por valor e por faixa, ordenações e junções.
- No índice composto, a ordem das colunas importa, e a busca precisa começar pelas primeiras colunas.
- Funções, conversões de tipo e curingas no início impedem a busca direta no índice.
- Cada índice ocupa espaço e torna as gravações mais lentas.
- A lentidão orienta a investigação, mas não prova que um índice está danificado.
Se os índices aceleram as buscas, por que não criar um índice para cada coluna?
Porque cada índice ocupa espaço e precisa ser atualizado nas gravações. Um índice que nenhuma consulta usa só aumenta o custo de gravar. A escolha acompanha as buscas e as ordens que o sistema realmente usa.
Existe um índice na coluna data_venda, mas a consulta com WHERE DATE(data_venda) = '2026-10-07' continua lenta. Por quê?
A função DATE transforma o valor de cada linha antes da comparação, e o índice guarda os valores originais. O servidor precisa calcular a função em todas as linhas. A mesma busca, escrita como faixa, com data_venda >= '2026-10-07' AND data_venda < '2026-10-08', usa o índice.