MySQL: Introdução às consultas do MySQL e ao plano de…
Última atualização: 2026-08-26
Só é possível escrever consultas com desempenho realmente alto se você compreender os recursos avançados dos índices.
Esta aula oferece uma explicação detalhada sobre os tipos de índice e a análise EXPLAIN.
1. O que você vai aprender
- Índice agrupado x Índice não agrupado
- Índice de cobertura
- Índices compostos e o prefixo mais à esquerda
- Situações em que os índices ficam inativos
- Interpretação do plano de execução do EXPLAIN
2. Índices agrupados e índices não agrupados
| Dimensão | Índice agrupado | Índice não agrupado |
|---|---|---|
| Método de armazenamento | Os dados e os índices são armazenados juntos | Os índices apontam para os endereços dos dados |
| Quantidade | Permitido apenas um | Permitidos vários |
| Chave primária | O InnoDB usa automaticamente a chave primária | Índice secundário |
| Consulta | Recupera dados diretamente | Requer consulta a uma tabela |
(1) Pesquisa em uma tabela
graph LR
A[Secondary Index<br/>idx_email] -->|Primary Key Value| B[Clustered Index<br/>PRIMARY]
B -->|Complete Data| C[Data Row]
-- The process of table lookup
SELECT * FROM users WHERE email = 'alice@email.com';
-- 1. Find id=1 in idx_email
-- 2. Find complete data for id=1 in PRIMARY
3. Índices de cobertura
Todos os campos da consulta estão incluídos no índice, portanto, não há necessidade de consultar a tabela.
▶ Exemplo: Índice de sobreposição
-- Create a composite index
CREATE INDEX idx_name_email ON users(username, email);
-- Covering Index(No need to return to the table)
SELECT username, email FROM users WHERE username = 'alice';
-- Non-covering index(Need to return to the table)
SELECT * FROM users WHERE username = 'alice';
| Tipo | Retorna à tabela | Desempenho |
|---|---|---|
| Índice de cobertura | N.º | Rápido |
| Índice sem cobertura | Sim | Lento |
4. Índices compostos e o prefixo mais à esquerda
(1) O Princípio do Prefixo Mais à Esquerda
O índice composto (a, b, c) pode ser utilizado nas seguintes consultas:
WHERE a = 1 -- ✅ Using index
WHERE a = 1 AND b = 2 -- ✅ Using index
WHERE a = 1 AND b = 2 AND c = 3 -- ✅ Using index
WHERE b = 2 -- ❌ Index not used
WHERE b = 2 AND c = 3 -- ❌ Index not used
▶ Exemplo: Verificação do uso de índices
CREATE INDEX idx_abc ON orders(customer_id, status, order_date);
-- ✅ Using index
EXPLAIN SELECT * FROM orders WHERE customer_id = 1;
EXPLAIN SELECT * FROM orders WHERE customer_id = 1 AND status = 'paid';
EXPLAIN SELECT * FROM orders WHERE customer_id = 1 AND status = 'paid' AND order_date > '2026-01-01';
-- ❌ Index not used (Violates the Leftmost Prefix Rule)
EXPLAIN SELECT * FROM orders WHERE status = 'paid';
5. Situações em que os índices se tornam ineficazes
| Cenário | Exemplo | Motivo |
|---|---|---|
| Operações com funções | WHERE YEAR(date) = 2026 |
Índice delimitado por uma função |
| Conversão implícita | WHERE phone = 13800001111 |
Consulta de matrizes de strings usando números |
| SEMELHANTE à esquerda, difuso | WHERE name LIKE '%john' |
Prefixo incerto |
| Condição OR | WHERE a = 1 OR b = 2 |
Alguns campos não estão indexados |
| NÃO ESTÁ/NÃO EXISTE | WHERE id NOT IN (1,2) |
O otimizador seleciona uma varredura completa da tabela |
| IS NULL/IS NOT NULL | WHERE col IS NULL |
Depende da proporção de valores NULL |
▶ Exemplo: Falha e recuperação do índice
-- ❌ Index Invalidation
SELECT * FROM users WHERE YEAR(created_at) = 2026;
-- ✅ Fix: Change to a range query
SELECT * FROM users WHERE created_at >= '2026-01-01' AND created_at < '2027-01-01';
-- ❌ Index Invalidation
SELECT * FROM users WHERE phone = 13800001111;
-- ✅ Fix: Use quotes
SELECT * FROM users WHERE phone = '13800001111';
6. Plano de execução do EXPLAIN
▶ Exemplo: Como usar o EXPLAIN
EXPLAIN SELECT * FROM users WHERE email = 'alice@email.com';
Saída:
+----+-------+------+---------+------+----------+-------+
| id | type | key | key_len | ref | rows | Extra |
+----+-------+------+---------+------+----------+-------+
| 1 | const | idx_email | 402 | const | 1 | |
+----+-------+------+---------+------+----------+-------+
(1) Descrições dos campos-chave
| Campo | Descrição | Valores válidos |
|---|---|---|
| tipo | Tipo de acesso | const > eq_ref > ref > range > index > ALL |
| chave | Índice utilizado | Não NULL |
| linhas | Número estimado de linhas a serem verificadas | Quanto menor, melhor |
| Extra | Informações adicionais | Uso do índice (índice abrangente) |
(2) Tipo de acesso
| Tipo | Descrição | Prós e contras |
|---|---|---|
| const | Consultas de igualdade de chave primária/índice único | ⭐⭐⭐ |
| eq_ref | Usar chave primária/índice único para junções | ⭐⭐⭐ |
| ref | Consultas de igualdade em índices não exclusivos | ⭐⭐ |
| intervalo | Consulta de intervalo de índice | ⭐⭐ |
| índice | Varredura completa do índice | ⭐ |
| TODOS | Varredura completa da tabela | ❌ |
❓ Perguntas Frequentes
P: Como devo escolher a ordem dos campos para um índice composto? R: Coloque primeiro os campos com alta seletividade e os campos com alta frequência de consulta.
P: Os valores das “linhas” no EXPLAIN são precisos? R: São estimativas, não valores exatos. No entanto, podem ser usados para avaliar a eficiência da consulta.
P: O que devo fazer se um índice deixar de ser eficaz? R: Reescreva o SQL para evitar situações em que o índice deixe de ser eficaz ou crie um índice de função (MySQL 8.0+).
P: Os valores da coluna “rows” no EXPLAIN são precisos? R: São estimativas, não valores exatos, mas você pode avaliar a eficácia das otimizações comparando as variações relativas. Use ANALYZE TABLE para atualizar as estatísticas.
P: Quando se deve usar um índice de prefixo? R: Quando um campo VARCHAR é muito longo e o prefixo é suficientemente distinto. Por exemplo,
INDEX(email(10))— desde que os primeiros 10 caracteres tenham um grau de distinção superior a 95%.
📖 Resumo
- Índices agrupados armazenam dados e índices juntos, enquanto índices não agrupados exigem uma consulta à tabela.
- Índice abrangente: Todos os campos da consulta estão incluídos no índice, portanto, não há necessidade de consultar a tabela.
- Prefixo mais à esquerda: um índice composto realiza a correspondência da esquerda para a direita
- Cenários de invalidação de índice: funções, conversões implícitas, fuzzy à esquerda, OR
- EXPLAIN Analise o plano de consulta, com foco em tipo/chave/linhas
📝 Exercícios
-
Pergunta básica (Dificuldade: ⭐): Use
EXPLAINpara analisar uma consulta e determinar se um índice está sendo utilizado. -
Problema avançado (Dificuldade ⭐⭐): Crie um índice composto para verificar o princípio do prefixo mais à esquerda.
-
Questão desafiadora (Dificuldade: ⭐⭐⭐): Identifique três cenários em que os índices são ineficazes e proponha soluções.