Olá, dev! Seja bem-vindo ao Dia 06 do seu plano de preparação para a certificação MongoDB Associate Developer. Hoje daremos um passo avançado: aprenderemos a diagnosticar o desempenho de consultas com o método explain(), aplicar a Regra ESR para desenhar índices perfeitos e construir Covered Queries para atingir performance máxima.
1. Diagnosticando Consultas com `explain()`
O método explain() revela o plano de execução escolhido pelo otimizador do MongoDB. Ele aceita três modos de verbosidade (Verbosity Modes):
"queryPlanner"(Padrão): Mostra o plano escolhido sem executar a consulta real no banco."executionStats": Executa a consulta e traz estatísticas detalhadas de execução (tempo em milissegundos, quantidade de itens lidos vs retornados)."allPlansExecution": Traz estatísticas da avaliação de todos os planos candidatos testados pelo otimizador.
// Analisando a execução real da consulta
db.pedidos.find({ status: "ENTREGUE", valor: { $gt: 500 } })
.sort({ dataCriacao: -1 })
.explain("executionStats")
Estágios Chave do Plano de Execução (Execution Stages):
COLLSCAN: Varredura total da coleção. Deve ser evitado em coleções de produção.IXSCAN: Varredura de índice (Index Scan). Indica que a consulta utilizou um índice.FETCH: Busca dos documentos reais no arquivo de dados a partir das referências do índice.SORT: Ordenação feita em memória RAM.
Métricas Essenciais do `executionStats`:
nReturned: Número de documentos retornados pela consulta ao cliente.totalKeysExamined: Quantidade de entradas de índice inspecionadas durante a busca.totalDocsExamined: Quantidade de documentos lidos em memória/disco no estágioFETCH.
Proporção Ideal: Quanto mais próximo totalKeysExamined estiver de nReturned, mais eficiente é o índice. Se totalDocsExamined for muito superior a nReturned, o índice precisa ser otimizado.
2. A Regra ESR (Equality, Sort, Range)
A Regra ESR é a diretriz mais cobrada no exame para determinar a ordem exata dos campos ao criar Índices Compostos:
- E — Equality (Igualdade): Posicione primeiro os campos testados por correspondência exata (ex:
status: "ATIVO"). Isso reduz drasticamente o escopo de busca da B-tree. - S — Sort (Ordenação): Posicione em segundo lugar os campos utilizados na ordenação (ex:
sort({ dataCriacao: -1 })). Isso permite usar a ordenação nativa do índice e evita o estágioSORTem memória. - R — Range (Intervalo): Posicione por último os campos que utilizam filtros de alcance ou desigualdade (ex:
$gt,$lt,$in,$ne).
Exemplo de Aplicação ESR:
Dada a consulta:
db.pedidos.find({
clienteId: 1002, // Equality
valorTotal: { $gte: 250 } // Range
}).sort({ dataPedido: -1 }) // Sort
Seguindo rigorosamente a ordem E $\rightarrow$ S $\rightarrow$ R, o índice composto ideal é:
db.pedidos.createIndex({
clienteId: 1, // E
dataPedido: -1, // S
valorTotal: 1 // R
})
3. Covered Queries (Consultas Cobertas)
Uma Covered Query é o padrão-ouro de desempenho no MongoDB. Ocorre quando 100% dos campos solicitados no filtro e na projeção da consulta fazem parte do próprio índice.
Por que a Covered Query é tão veloz?
O MongoDB responde à consulta lendo exclusivamente os dados da árvore B em memória RAM, eliminando completamente o estágio `FETCH` em disco. No `explain("executionStats")`, o campo totalDocsExamined será exatamente 0.
Condições Obrigatórias para ser uma Covered Query:
- Todos os campos do filtro estão no índice.
- Todos os campos na projeção estão no índice.
- O campo
_idé explicitamente excluído da projeção ({ _id: 0 }), a menos que o_idfaça parte das chaves do índice composto. - Nenhum dos campos indexados é um array (índices Multikey não suportam consultas cobertas).
// Criando o índice cobridor
db.usuarios.createIndex({ status: 1, email: 1, nome: 1 })
// Consulta Coberta (Covered Query)
db.usuarios.find(
{ status: "ATIVO", email: "dev@empresa.com" },
{ _id: 0, email: 1, nome: 1 } // Exclusão do _id é mandatória!
)
4. Questões no Estilo Exame de Certificação
Questão 1: Considere a seguinte consulta: db.produtos.find({ categoria: "Eletrônicos", preco: { $gt: 100 } }).sort({ nome: 1 }). Qual das opções de índice composto a seguir segue estritamente a Regra ESR para máxima performance?
A) { preco: 1, nome: 1, categoria: 1 }
B) { categoria: 1, preco: 1, nome: 1 }
C) { categoria: 1, nome: 1, preco: 1 }
D) { nome: 1, categoria: 1, preco: 1 }
Resposta Correta: C. Seguindo ESR: Equality (categoria) $\rightarrow$ Sort (nome) $\rightarrow$ Range (preco), formando a chave { categoria: 1, nome: 1, preco: 1 }.
Questão 2: Um desenvolvedor executou explain("executionStats") para uma consulta e observou: totalKeysExamined: 50, totalDocsExamined: 0 e nReturned: 50. O que essa métrica indica?
A) A consulta realizou um COLLSCAN.
B) A consulta falhou por ultrapassar 32 MB em memória.
C) A consulta foi uma Covered Query (Consulta Coberta) perfeita.
D) O índice utilizado é um Multikey Index.
Resposta Correta: C. Quando totalDocsExamined === 0 e nReturned === totalKeysExamined, todos os dados foram obtidos diretamente do índice sem necessidade de estágio FETCH.