Introdução
Um passo a passo para você abrir, usar e validar a nova tela Profiler. Siga do Passo 1 até o fim, na ordem. Cada passo diz o que fazer e o que você vai ver. Não precisa saber nada de profiling antes — as caixas 💡 explicam os conceitos na hora em que aparecem.
Como ler este manual
Cada passo tem:
- Fazer — a ação exata (clique, digite, rode tal script).
- Ver — o que deve acontecer na tela. É o seu “passou / não passou”.
- Por quê — só quando ajuda a entender (pode pular se tiver pressa).
Conceito
Caixa de conceito. Explica um termo na hora em que ele aparece.
Atenção
Atenção. Um detalhe que costuma confundir.
Antes de começar
Conceito
O que é o Profiler
O MongoDB consegue gravar um “diário de bordo” de tudo que executa — cada consulta, quanto demorou, se usou índice — numa coleção chamada system.profile. A tela Profiler liga esse diário e o mostra de forma gráfica: gráficos, filtros, e até recomendações de índice.
Você vai precisar de:
- 1O dev server reiniciado depois do último build (sem isso a tela nem carrega — é o que causa o erro
spacingPx). - 2Uma conexão MongoDB conectada. Pode ser local, on-prem ou Atlas M10+. No Atlas M0/M2/M5 (gratuito) o profiler é bloqueado pela MongoDB — funciona, mas a tela vai avisar que está restrito (testamos isso no Passo 41).
- 3O usuário do banco precisa poder rodar comandos de administração (
setProfilingLevel,createIndex). Um usuário “dono do banco” resolve.
Tempo estimado do roteiro completo: ~30 minutos.
Preparar o banco de laboratório
Para o Profiler ter o que mostrar, primeiro criamos um banco com bastante dado.
Criar o banco profiler_lab
Abra a aba Mongo Shell (ou o Scratchpad) do NoSqlStudio, cole o script abaixo e execute.
use profiler_lab;
db.dropDatabase();
use profiler_lab;
['orders', 'products', 'customers'].forEach((c) => db.getCollection(c).drop());
function seed(coll, n, gen) {
const c = db.getCollection(coll);
let buf = [];
for (let i = 0; i < n; i++) {
buf.push(gen(i));
if (buf.length === 165000) { c.insertMany(buf); buf = []; }
}
if (buf.length) c.insertMany(buf);
print(coll + ': ' + c.countDocuments());
}
const ST = ['pending', 'paid', 'shipped', 'cancelled', 'refunded'];
const RG = ['north', 'south', 'east', 'west'];
seed('orders', 120000, (i) => ({
orderNo: i, status: ST[i % 5], region: RG[i % 4],
customerId: (i * 7) % 5000, total: Math.round(Math.random() * 1e5) / 100,
items: 1 + (i % 8), createdAt: new Date(Date.now() - (i % 90) * 864e5),
note: 'order line '.repeat(4),
}));
seed('products', 20000, (i) => ({
sku: 'SKU-' + i, category: ['a', 'b', 'c', 'd', 'e'][i % 5],
price: Math.round(Math.random() * 5e4) / 100, stock: i % 500,
active: i % 3 !== 0,
}));
seed('customers', 5000, (i) => ({
customerId: i, tier: ['free', 'pro', 'enterprise'][i % 3],
city: RG[i % 4], spend: Math.round(Math.random() * 1e6) / 100,
}));O shell imprime, depois de alguns segundos:
orders: 120000
products: 20000
customers: 5000120 mil pedidos é o suficiente para uma consulta sem índice ficar visivelmente lenta — e lentidão é exatamente o que queremos diagnosticar.
Atenção
Se mais à frente as consultas não passarem de 100 ms (máquina rápida), volte aqui e troque 120000 por 300000.
Abrir a tela Profiler
Abrir pela primeira vez
Abra o Profiler de um destes 3 jeitos (todos levam ao mesmo lugar — teste os outros dois mais tarde, no Passo 46):
- Menu principal → Database Profiler, ou o atalho Ctrl+Alt+Shift+P.
- Barra de ferramentas → menu Monitoring → Database Profiler.
- Clique com o botão direito numa conexão na barra lateral → Profiler.
Abre uma nova aba chamada Profiler, com o nome da conexão ao lado. A aba tem, de cima para baixo: uma barra de cabeçalho, uma faixa de controle, e quatro botões de seção (Dashboard, Live Feed, Index Advisor, Sessions).
Escolher o banco
No cabeçalho, no campo Database, escolha `profiler_lab`.
A tela passa a trabalhar sobre esse banco. Como ainda não ligamos o profiling, o Dashboard mostra uma mensagem do tipo “Sem dados de profiling ainda”.
Atenção
O profiler é por banco. Tudo deste manual usa profiler_lab. Se escolher outro banco, não verá as provocações.
Ligar o profiling
Entender a faixa de controle
Logo abaixo do cabeçalho há uma faixa com:
- Profiling — três botões:
Off·Slow ops·All ops. - slowms e Sample — dois campos numéricos + botão Apply.
- Filtro — abre um construtor de filtro.
- ⏱ Captura — captura cronometrada segura.
- system.profile — uma barrinha de uso da coleção + botão Resize.
- Saúde — uma nota (A–F) com pontuação.
Conceito
Os três níveis. Off = não grava nada. Slow ops = grava só o que passou do limite slowms. All ops = grava tudo. Para testar, vamos de All ops para ver todo movimento.
Ligar no nível “All ops”
Clique no botão All ops.
- A bolinha de status à esquerda fica azul.
- Aparece uma pílula de aviso “⚠ Todas as ops” (lembrete de que o nível 2 tem custo de desempenho).
- Uma mensagem rápida confirma “Profiling level set to 2”.
Este é o coração da ferramenta. No profiler antigo isso só copiava um comando para você colar no shell. Agora o clique liga o profiling de verdade. Se a bolinha ficou azul, o caminho técnico principal funcionou. ✅
Gerar movimento (as “provocações”)
Agora vamos rodar consultas no shell para o Profiler ter o que mostrar. Mantenha a aba Profiler aberta — ela atualiza sozinha a cada poucos segundos.
Provocação A — consultas lentas
Rode no shell:
use profiler_lab;
db.orders.find({ status: 'shipped' }).toArray().length;
db.orders.find({ region: 'south' }).sort({ total: -1 }).toArray().length;Em 1–3 segundos, na seção Live Feed, duas linhas novas de operação query em profiler_lab.orders, com um selo vermelho COLLSCAN.
Conceito
COLLSCAN x IXSCAN. COLLSCAN = o MongoDB leu documento por documento porque não havia índice — lento. IXSCAN = ele usou um índice (um atalho) — rápido. Selo vermelho = ruim; selo azul = bom.
Provocação B — consulta ineficiente
Rode no shell:
use profiler_lab;
db.orders.find({ status: 'refunded', region: 'north', items: 7 }).toArray();Mais uma linha no feed. Na coluna Examined → Returned o número fica vermelho — examinou 120 mil documentos para devolver poucos.
Conceito
Ineficiente. Quando o banco “examina” muito mais do que “retorna”, ele está desperdiçando trabalho — forte candidata a ganhar um índice.
Provocação C — escritas
Rode no shell:
use profiler_lab;
db.orders.insertOne({ orderNo: 999001, status: 'paid', region: 'east', items: 2 });
db.orders.updateMany({ status: 'pending' }, { $set: { flagged: true } });
db.orders.deleteMany({ flagged: true, items: 3 });Três operações novas: insert, update, remove.
Provocação D, E, F — agregação, contagem e cursores
Rode no shell:
use profiler_lab;
db.orders.aggregate([
{ $match: { status: 'paid' } },
{ $group: { _id: '$region', n: { $sum: 1 }, rev: { $sum: '$total' } } },
]).toArray();
db.orders.countDocuments({ region: 'west' });
db.orders.distinct('status');
let cur = db.orders.find({}).batchSize(500).limit(5000);
let k = 0; while (cur.hasNext()) { cur.next(); k++; } print(k);Operações dos tipos command (a agregação, a contagem) e várias getmore (o cursor que lê em lotes).
Provocação G — a mesma consulta repetida
Rode no shell:
use profiler_lab;
for (let i = 0; i < 40; i++) db.orders.find({ status: 'paid' }).limit(10).toArray();Nada de especial no feed agora — mas guarde: no Passo 24 isso vira uma única linha no painel de “Query shapes”, com contagem 40.
Explorar o Live Feed
Abrir o feed
Clique na seção Live Feed (no topo).
Uma tabela com as operações, a mais recente em cima. Colunas: hora, tipo, coleção, duração (colorida — verde rápido, vermelho lento), plano (selo COLLSCAN/IXSCAN), examinados→retornados, e app. No topo, “X de Y operações”.
Ver o modo ao vivo funcionando
Rode de novo a Provocação A (a do Passo 6) e fique de olho no feed:
use profiler_lab;
db.orders.find({ status: 'shipped' }).toArray().length;
db.orders.find({ region: 'south' }).sort({ total: -1 }).toArray().length;Linhas novas aparecem sozinhas no topo em segundos.
Pausar e retomar
No cabeçalho, clique no botão ● Live (ele vira ⏸ Pausado). Rode a Provocação A de novo:
use profiler_lab;
db.orders.find({ status: 'shipped' }).toArray().length;
db.orders.find({ region: 'south' }).sort({ total: -1 }).toArray().length;O feed não cresce — está congelado. Clique em ⏸ Pausado para voltar a ● Live: ele volta a crescer.
Pausar é útil para inspecionar uma linha sem a lista pulando.
Filtros rápidos (os chips de preset)
Clique, um de cada vez, nos chips no topo do feed:
- Lentas > 100ms — só operações lentas.
- COLLSCANs — só as sem índice (selo vermelho).
- Ineficientes — destaca a do Passo 7.
- Writes — só insert/update/remove (as do Passo 8).
- Últimos 5 min — só o movimento recente.
A tabela encolhe para mostrar só o que casa. O chip ativo fica destacado. Clique de novo para desligar.
Filtros finos
Faça, em sequência:
- 1Clique nos chips de tipo (
query,insert,getmore…) para ligar/desligar. - 2No dropdown Todas as coleções, escolha
orders. - 3Na busca, digite
refunded.
Cada filtro estreita a lista. Eles se combinam.
Limpar tudo
Clique em Limpar filtros (aparece quando há filtro ativo).
A tabela volta a mostrar tudo.
Explorar o Dashboard
Abrir o Dashboard
Clique na seção Dashboard.
Quatro cartões de número no topo (Operações, Ops lentas, Varreduras de coleção, Duração média) e, abaixo, vários gráficos.
Os indicadores (KPIs)
Os quatro números refletem tudo que você provocou. “Varreduras de coleção” mostra a porcentagem de COLLSCANs — quanto maior, pior.
Linha do tempo
O gráfico Operações ao longo do tempo mostra faixas empilhadas por tipo (leituras, inserts, updates, deletes, comandos), com legenda colorida.
Uso de índices (rosca)
O gráfico de rosca Uso de índices divide as operações em COLLSCAN (vermelho), IXSCAN (azul) e outras. Hoje deve estar dominado por vermelho.
Distribuição de latência
Barras agrupando as operações por faixa de tempo (0–1ms, …, >5s).
Coleções mais quentes (treemap)
Blocos proporcionais ao tempo total gasto em cada coleção. orders deve ser o maior bloco.
Clicar num bloco do treemap
Clique no bloco orders.
A tela pula para o Live Feed já filtrado por orders. (Volte ao Dashboard depois.)
Formas de consulta (query shapes)
A tabela Query shapes agrupa consultas com o mesmo “formato”. A consulta que você repetiu 40× no Passo 10 aparece como uma linha só, com contagem 40 e o tempo somado.
É assim que você descobre “qual consulta, somando todas as vezes, mais pesa no banco” — mesmo que cada execução individual seja rápida.
Operações mais lentas
A tabela final lista as 8 operações mais demoradas. Guarde para o próximo passo.
Investigar uma operação (drill-down)
Abrir o painel de detalhe
Clique em qualquer linha — no Live Feed, na tabela de query shapes, ou na de mais lentas.
Um painel desliza da direita com o detalhe completo da operação.
Ler os números
Uma grade com Duração, Plano, Yields, Docs examinados, Chaves examinadas, Retornados. Se a operação for ineficiente, um aviso vermelho diz que ela é “forte candidata a índice”.
Pedir o “explain” ao vivo
Clique em Explicar esta consulta.
A ferramenta roda o explain() na hora e mostra o plano real, o tempo de execução e quantos documentos foram examinados — útil para confirmar o diagnóstico no banco atual.
Conceito
Explain. É o MongoDB descrevendo como pretende executar a consulta. Confirma se ela usaria índice ou não.
Ver o comando e os detalhes
No painel, veja a seção Comando (o JSON da operação) e clique no ícone de copiar. Depois clique em Execution stats e Documento bruto para expandir/recolher.
O comando é copiado para a área de transferência; as seções abrem e fecham.
Fechar o painel
Feche pelo X no topo do painel — e abra outro e feche clicando na área escurecida ao lado.
O painel some das duas formas.
Usar o Index Advisor (o destaque)
Gerar recomendações
Rode no shell (são 3 consultas problemáticas, repetidas 30×):
use profiler_lab;
for (let i = 0; i < 30; i++) {
db.orders.find({ status: 'shipped' }).toArray();
db.orders.find({ region: 'north' }).sort({ createdAt: -1 }).limit(20).toArray();
db.products.find({ category: 'c', active: true }).toArray();
}Aguarde uns segundos. (Continua no próximo passo.)
Abrir o Index Advisor
Clique na seção Index Advisor.
No topo, um cartão de Saúde com uma nota (A–F) — provavelmente baixa (C/D), porque você gerou muitos COLLSCANs. Abaixo, uma lista de recomendações de índice — cerca de 3 cartões.
Ler uma recomendação
Cada cartão tem: uma pílula de severidade (Alta/Média/Baixa), a coleção, o “formato” da consulta, chips com os campos do índice sugerido (com setas ↑/↓) e uma linha de impacto (“N operações · X s no total · M varreduras”).
Conceito
Por que esses campos nessa ordem. O advisor segue a regra ESR: campos de igualdade primeiro, depois os de ordenação, depois os de faixa. É a ordem que torna o índice mais eficiente.
Criar um índice com 1 clique
Num cartão, clique em Criar índice. Confira o comando no modal e confirme.
Uma mensagem “Índice criado”. O cartão daquela recomendação muda para ✓ Já indexado.
Criar os demais
Repita o Passo 34 para as outras recomendações.
Todas viram ✓ Já indexado.
Confirmar que melhorou
Rodar as mesmas consultas de novo
Rode outra vez o mesmo script do Passo 31 (repetido aqui para você não precisar voltar):
use profiler_lab;
for (let i = 0; i < 30; i++) {
db.orders.find({ status: 'shipped' }).toArray();
db.orders.find({ region: 'north' }).sort({ createdAt: -1 }).limit(20).toArray();
db.products.find({ category: 'c', active: true }).toArray();
}As consultas rodam de novo — agora com os índices que você criou na Etapa 8 já em vigor.
Ver o COLLSCAN virar IXSCAN
Vá ao Live Feed.
As mesmas consultas agora aparecem com selo azul IXSCAN e duração bem menor. Antes liam 120 mil documentos; agora usam o índice.
Ver a nota de Saúde subir
Volte ao Index Advisor (ou clique na pílula Saúde no painel de controle).
A nota subiu (ex.: de C/D para A/B) e há menos recomendações. Você acabou de fazer um ciclo completo: diagnosticar → corrigir → comprovar. ✅
Sessões e relatório
Conceito
Sessão. Uma “foto” do estado atual do profiling, salva com um nome. Serve para comparar “antes” e “depois” de uma mudança.
Salvar uma sessão
Vá em Sessions, digite um nome (ex.: depois dos indices) e clique em Salvar sessão.
A sessão aparece na lista, com seus indicadores e a data.
Comparar
Na lista, selecione duas entradas — por exemplo a sessão salva e a Janela atual (que está sempre no topo).
Surge uma tabela de Comparação com a coluna Δ colorida — verde quando melhorou (menos COLLSCAN, menos tempo), vermelho quando piorou.
Exportar o relatório
Clique em Exportar relatório.
Baixa um arquivo .json com saúde, recomendações, formas de consulta e as operações mais lentas — para anexar a um chamado ou guardar.
Recursos de controle e segurança
Captura cronometrada segura
Conceito
Por que existe. Deixar o nível 2 ligado e esquecer é perigoso em produção. A “captura” liga o nível 2, faz uma contagem regressiva e desliga sozinha no fim.
Na faixa de controle, clique em ⏱ Captura e escolha 30s. Durante esses 30s, rode uma provocação qualquer — por exemplo a Provocação A:
use profiler_lab;
db.orders.find({ status: 'shipped' }).toArray().length;
db.orders.find({ region: 'south' }).sort({ total: -1 }).toArray().length;O profiling vai para nível 2 e aparece uma pílula com a contagem regressiva. Ao zerar, o nível volta sozinho ao que estava antes, com a mensagem “Captura concluída”. (Você também pode clicar em Cancelar para encerrar antes.)
Filtro de profiling
Clique em Filtro, preencha Namespace com orders e clique em Aplicar filtro. Em seguida rode a Provocação A:
use profiler_lab;
db.orders.find({ status: 'shipped' }).toArray().length;
db.orders.find({ region: 'south' }).sort({ total: -1 }).toArray().length;Depois clique em Filtro → Limpar filtro.
Com o filtro ativo, só operações em orders são gravadas (e o botão mostra “Filtro ativo”). Ao limpar, volta a gravar tudo.
Gerenciar a coleção system.profile
Conceito
Capped collection. O diário do profiler tem tamanho fixo; quando enche, apaga o mais antigo. O padrão (1 MB) enche rápido.
Observe a barrinha system.profile na faixa de controle (mostra usado / total). Clique em Resize, escolha 10 MB e confirme.
A barra passa a refletir ~/10 MB. O modal avisa que o histórico atual é apagado no redimensionamento.
Ajustar slowms e taxa de amostragem
Mude slowms para 50 e clique em Apply. Depois clique em Slow ops e rode a Provocação A:
use profiler_lab;
db.orders.find({ status: 'shipped' }).toArray().length;
db.orders.find({ region: 'south' }).sort({ total: -1 }).toArray().length;No nível “Slow ops” só entram no feed operações mais lentas que o slowms definido — as rápidas são ignoradas.
Acabamento
Outros jeitos de abrir
Teste os 3 pontos de entrada do Passo 2 que você ainda não usou.
Todos abrem a aba Profiler. Se já houver uma aberta, ele foca a existente em vez de duplicar.
Idiomas
Em Settings → Language, troque o idioma (são 5). Volte ao Profiler.
Toda a tela do Profiler aparece traduzida — sem textos “crus” tipo profiler.xyz.
Temas
Alterne o tema entre Light, Dark e Neon.
Cores, cartões e gráficos se adaptam; nada de texto invisível.
Limpeza (quando terminar)
Rode no shell:
use profiler_lab;
db.setProfilingLevel(0);
db.dropDatabase();O profiling é desligado e o banco de laboratório some.
Resumo do que você validou
| Etapa | Funcionalidade |
|---|---|
| 2–3 | Abrir o Profiler (3 entradas) + escolher banco |
| 3 | Ligar o profiling de verdade (Off / Slow / All) |
| 4–5 | Live Feed: tempo real, pausar, presets, filtros, busca |
| 6 | Dashboard: KPIs, linha do tempo, rosca, latência, treemap, query shapes |
| 7 | Drill-down: detalhes, explain() ao vivo, comando, raw |
| 8–9 | Index Advisor: recomendações, criar índice, comprovar a melhora |
| 10 | Sessões: salvar, comparar, exportar relatório |
| 11 | Captura cronometrada, filtro, resize, slowms |
| 12 | Entradas alternativas, 5 idiomas, 3 temas |