No post anterior EXPLAIN bonito, índice inútil: A vida real no MySQL trouxe sobre como avaliar índices: quando fazem sentido, quando não ajudam e como identificar desperdícios.
Agora chegou a parte mais importante….. usar esses índices corretamente nas consultas.
Índice bom não salva query ruim.
E query ruim costuma ter sempre os mesmos vícios.
Neste post focaremos em:
- Como o B‑Tree realmente funciona
- Por que a ordem das colunas importa
- Padrões de consulta que quebram o uso de índice
- Como reescrever SQL para aproveitar índices existentes
Tudo com exemplos reais.
Como o MySQL usa um índice B‑Tree (na prática)
Índices no InnoDB são organizados como B‑Tree, o que significa:
- Os dados são armazenados ordenados
- A busca só é eficiente quando seguimos essa ordem
- O MySQL não “pula” colunas dentro do índice
|
1 |
INDEX idx_cliente_data_status (cliente_id, data_pedido, status) |
|
1 |
WHERE cliente_id = 10 |
|
1 |
WHERE cliente_id = 10 AND data_pedido >= '2024-01-01' |
|
1 |
WHERE cliente_id = 10 AND data_pedido = '2024-01-15' AND status = 'PAGO' |

|
1 |
WHERE data_pedido = '2024-01-15' |
|
1 |
WHERE status = 'PAGO' |
|
1 |
WHERE data_pedido >= '2024-01-01' AND status = 'PAGO' |

Regra de ouro: condição começa da esquerda
Esse conceito é conhecido como Leftmost Prefix Rule.
Um índice (A, B e C) pode ser usado como:
- (A)
- (A, B)
- (A, B, C)
- (B)
- (C)
- (B, C)
Isto não é sobre a ordem do WHERE, e sim sobre quais colunas estão presentes.
Isso funciona:
|
1 |
WHERE B = 1 AND A = 2 |
Se existe índice (A, B) o otimizador rearranja internamente.
O problema não é a ordem do WHERE. É pular colunas do índice.
Funções e expressões: o maior sabotador de índices
Outro ponto mais comum é aplicar funções em coluna indexadas.
|
1 |
WHERE DATE(data_pedido) = '2024-01-15' |
Mesmo com índice em data_pedido, isso invalida o uso.
✅ Forma correta:
|
1 |
WHERE data_pedido >= '2024-01-15 00:00:00' AND data_pedido < '2024-01-16 00:00:00' |
|
1 |
WHERE YEAR(data_pedido) = 2024 |

LIKE, curingas e armadilhas silenciosas
Índices podem ser usados com LIKE, mas só se respeitarem o prefixo.
✅ Usa índice:
|
1 |
WHERE email LIKE 'henrique%' |
❌ Não usa índice (full scan):
|
1 |
WHERE email LIKE '%@gmail.com' |
Se o curinga vem antes, o B‑Tree não ajuda.
📌 Dica prática:
- Para buscas desse tipo, pense em colunas derivadas, índices funcionais (MySQL 8+) ou estratégias de modelagem.
ORDER BY e LIMIT: ouro mal aproveitado
|
1 |
INDEX idx_cliente_data (cliente_id, data_pedido) |
✅ Query eficiente:
|
1 |
SELECT * FROM pedidos WHERE cliente_id = 10 ORDER BY data_pedido DESC LIMIT 10; |
Aqui o MySQL:
- Usa o índice
- Já lê ordenado
- Para assim que encontra 10 linhas
❌ Query problemática seria:
|
1 |
ORDER BY data_pedido DESC |


Temos diversos fatores que influenciam na má utilização de um indice, acima demonstrei alguns cenários mais óbvios. Porém, não podemos esquecer de sempre olharmos o DATATYPE de sua coluna.
Um exemplo comúm que enfrento em alguns sistemas MySQL é:
|
1 2 3 |
cliente_id (CHAR) SELECT *FROM produto WHERE cliente_id = 10; |
Assim o desenvolver ou aplicação estará forçando o MySQL converter, e ignorando o índice dependendo do contexto.
No prompt:
Conclusão
Reescrever SQL quase sempre traz mais ganho do que criar novos índices ou mexer em parâmetros.
- Entender a ordem do índice.
- Evitar funções desnecessárias.
- Pensar em intervalos em vez de transformação de dados.
- Saber quando o índice pode ajudar e quando não pode.
REFERÊNCIAS.
Indices Multiplos – MySQL Documentation.
Entendendo Indexação – Percona Documentation
Como usar Indices – MySQL Documentation






