MongoDB: Otimização e monitoramento de desempenho

Última atualização: 2026-08-26

A otimização e o monitoramento do desempenho são a “última etapa” de um ambiente de produção — dominá-los pode evitar 90% dos incidentes de desempenho.

1. O que você vai aprender



100%
graph LR
    App[Node.js Applications] -->|Request| Pool[Connection Pool<br/>maxPoolSize=50]

    Pool -->|Connect 1| M1[mongod<br/>Primary]
    Pool -->|Connect 2| M2[mongod<br/>Secondary]
    Pool -->|Connect 3| M3[mongod<br/>Secondary]

    M1 -->|Copy| M2
    M1 -->|Copy| M3

    App -.->|explain| M1
    App -.->|indexStats| M1

    style Pool fill:#d4edda
    style M1 fill:#cce5ff

2. Ajuste do pool de conexões

Por que o pool de conexões é importante? Toda vez que o MongoDB estabelece uma conexão TCP, são necessários: um handshake de três vias + autenticação SCRAM (3 idas e voltas) + inicialização da sessão — o que leva aproximadamente 10–50 ms. Em cenários de alta simultaneidade, se não houver um pool de conexões, a criação de uma nova conexão para cada solicitação pode levar a uma tempestade de conexões que sobrecarrega o banco de dados. O pool de conexões reduz o tempo de estabelecimento da conexão para menos de 1 ms por meio do pré-aquecimento e da reutilização das conexões.

Como funcionam os pools de conexão:

100%
graph LR
    subgraph "Node.js Applications"
        R1[Request1] -->|Loan Out| Pool[(Connection Pool<br/>min=5 max=50)]
        R2[Request2] -->|Loan Out| Pool
        R3[Request3] -->|Wait in line| Queue[Waiting Queue<br/>waitQueueTimeoutMS]
    end
    
    Pool -->|Active Connections| Active[mongod Primary]
    Pool -->|Idle Connections| Idle[Free Space Recovery<br/>maxIdleTimeMS]
    R1 -.->|Return| Pool
    R3 -.->|Get the Return Link| Pool

    style Pool fill:#d4edda
    style Queue fill:#fff3cd
    style Active fill:#cce5ff

Guia para ajustar os parâmetros do pool de conexões:

Parâmetro Valor padrão Estratégia de ajuste Risco de definir um valor muito alto Risco de definir um valor muito baixo
maxPoolSize 100 Concorrência máxima × 1,5 Limite de conexões com o banco de dados atingido Tempo limite da fila de solicitações
minPoolSize 0 Definido como 10% do pico Inicialização lenta, alto consumo de memória Atraso na inicialização a frio
maxIdleTimeMS 0 30000 (30 segundos) Criação frequente de novas conexões Vazamentos de conexão
waitQueueTimeoutMS 0 10000 (10 segundos) Pilha de solicitações Solicitações em espera permanente
serverSelectionTimeoutMS 30000 5000 Atraso prolongado Falha rápida

Fórmula para calcular o número de conexões: maxPoolSize = peak concurrency * average query time (seconds) * safety factor (1.5). Por exemplo, se houver 100 conexões simultâneas e o tempo médio de consulta for de 0,1 segundo, então maxPoolSize = 100 * 0,1 * 1,5 = 15.

JAVASCRIPT
// === mongoose Connection Pool Configuration ===
mongoose.connect(uri, {
  maxPoolSize: 50,          // Maximum Number of Connections(Default 100)
  minPoolSize: 5,           // Minimum Number of Connections(Default 0)
  maxIdleTimeMS: 30000,     // Connection Idle Timeout(Default: Unlimited)
  waitQueueTimeoutMS: 10000 // Connection timeout
});

// === Monitor Connection Pool ===
const db = mongoose.connection.db;
const stats = await db.admin().command({ serverStatus: 1 });
console.log('Connections:', stats.connections);
maxPoolSize Aplicável
10 Pequenos aplicativos / Desenvolvimento
50 Aplicativos de médio porte / Serviços da Web
100 Aplicativos de grande porte / Alto tráfego
Mais de 200 Modo de cluster / Origem da CDN

3. Otimização de consultas

Metodologia de otimização de consultas: O objetivo principal da otimização de consultas é “reduzir a carga de trabalho do banco de dados” — por meio da varredura de menos documentos, da transferência de menos campos e da omissão de serializações desnecessárias. Etapas de otimização: ① Use explain() para diagnosticar o problema; ② Verifique se o índice foi acionado; ③ Reduza o número de campos retornados; ④ Reduza o número de registros retornados; ⑤ Omita a sobrecarga desnecessária do Mongoose.

Quatro técnicas essenciais para a otimização de consultas:

Técnica de otimização Princípio Efeito Código
a função hint() força o uso do índice contorna a escolha incorreta do otimizador de consultas COLLSCAN → IXSCAN .hint({field: 1})
projeção select() Retorna apenas os campos necessários Redução de mais de 90% na transferência de dados .select('sku title price')
lean() pular hidratação Não criar documento Mongoose Aumento de desempenho de 5x .lean()
limit() Limita o número de registros Evita que sejam retornados muitos documentos Reduz o uso de memória .limit(20)

Padrões comuns de consultas lentas e soluções:

Modo de consultas lentas Causa Solução
COLLSCAN (Varredura completa da tabela) Índice ausente ou falha no índice Criar um índice apropriado + hint()
Muitos campos retornados find() Não select Adicionar projeção .select()
$where + execução de JS Executar funções JS por documento Alternar para operadores nativos
$regex: sem âncora Não é possível usar o índice Adicione o prefixo ^ para definir uma âncora
Pular paginação detalhada pular (lento com conjuntos de dados grandes) Mudar para paginação por cursor
N+1 consultas Consultar uma a uma em um loop Mudar para $in ou $lookup

(1) A função hint() força a indexação

JAVASCRIPT
// === Force Index Usage ===
const products = await Product.find({ category: 'Electronics' })
  .hint({ category: 1 });

// === mongoose Equivalent ===
const products = await Product.find({ category: 'Electronics' })
  .hint('category_1');

(2) projeção: Reduzir o número de campos

JAVASCRIPT
// === Query only the necessary fields ===
const products = await Product.find()
  .select('sku title price')  // Don't fetch description, images, etc.
  .lean();

// === Reduce Network Traffic 90%+ ===

(3) O lean() ignora o hydrate

JAVASCRIPT
// === General Query: Build mongoose Document (slow) ===
const products = await Product.find();

// === lean(): Return plain object directly (fast) ===
const products = await Product.find().lean();

(4) Evite $where

JAVASCRIPT
// Slow: $where executes JavaScript
db.products.find({ $where: 'this.price > 1000' });

// Fast: Use $gt
db.products.find({ price: { $gt: 1000 } });

4. Análise de consultas lentas

Processo de análise de consultas lentas: Identifique as consultas lentas → Ative o Profiler → Analise explain() → Identifique os gargalos → Otimize → Verifique. Existem três níveis de perfilagem: 0 (desativado), 1 (registrar consultas lentas) e 2 (registrar todas as consultas). Use o Nível 1 em ambientes de produção; o Nível 2 acarreta uma sobrecarga de desempenho.

Fluxo de trabalho para diagnóstico de consultas lentas:

100%
graph TD
    Start[Identifying Slow Queries] --> Enable[Enable Profiling Level 1<br/>slowms=100]
    Enable --> Collect[Collect Slow Query Logs<br/>system.profile]
    Collect --> Explain[explain executionStats<br/>Analyze the Execution Plan]
    Explain --> Stage{Stage Type?}
    Stage -->|COLLSCAN| AddIdx[Add an Index]
    Stage -->|IXSCAN| CheckProj[Check the projection/Number of Articles]
    Stage -->|FETCH| OptProj[Optimization select]
    AddIdx --> Verify[Verify the effectiveness of the optimization]
    CheckProj --> Verify
    OptProj --> Verify
    Verify --> Done[Performance Meets Standards ✅]

    style COLLSCAN fill:#f8d7da
    style Done fill:#d4edda

A função explain() exibe os campos-chave:

Campo Descrição Valor normal Valor anormal
estágio Método de digitalização IXSCAN COLLSCAN
totalKeysExamined Chaves de índice verificadas ~ nReturned >> nReturned
totalDocsExamined Documentos digitalizados ~ nReturned >> nReturned
nRetornados Número de documentos retornados
executionTimeMillis Tempo de execução < 100 ms > 1000 ms
índice utilizado Índice utilizado Nome do índice composto Nenhum (COLLSCAN)

Proporção Áurea: totalDocsExamined : nReturned ≈ 1:1. Se, após a varredura de 10.000 registros, forem retornados apenas 20, isso significa que o índice não é preciso o suficiente.

JAVASCRIPT
// === Enable the slow query log ===
mongoose.connection.db.admin().command({
  setParameter: 1,
  slowms: 100  // Record > 100ms Queries
});

// === mongoose Enable in the middle debug ===
mongoose.set('debug', true);
// Output all queries to console

// === mongoose-debug Slow Query Log ===
mongoose.set('debug', (collectionName, method, query, doc) => {
  const start = Date.now();
  console.log(`${collectionName}.${method}(${JSON.stringify(query)})`);
});

5. Otimização de índices

Princípios fundamentais da otimização de índices: Ter mais índices não significa necessariamente que seja melhor — cada índice ocupa espaço em disco, aumenta a sobrecarga de gravação (já que os índices precisam ser atualizados a cada inserção, atualização ou exclusão) e consome memória (o MongoDB tenta manter os índices na RAM). O segredo para otimizar os índices é criar índices úteis, remover os desnecessários e escolher o tipo de índice correto.

Métricas de verificação de integridade do índice:

Parâmetro Como obter Valor normal Valor anormal
Uso do índice $indexStats accesses.ops > 0 ops = 0 (não utilizado)
Tamanho do índice db.stats() < 50% da RAM > RAM (troca frequente)
Número de índices getIndexes() < 10 / coleção > 20 (demais)
Latência de gravação status do servidor < 10 ms > 100 ms (o índice está retardando as gravações)

Decisões sobre otimização de índices:

Cenário Ação Motivo
Índice com ops=0 Excluir Puro desperdício de espaço e desempenho de gravação
Índices redundantes Manter índices compostos, remover índices de campo único {a:1, b:1} já abrange {a:1}
Índice de base baixa Excluir ou modificar alguns índices isActive tem apenas dois valores, portanto, apresenta baixa seletividade
Verificar se há índices não utilizados Adicionar ou usar hint() Desastre de desempenho com COLLSCAN
JAVASCRIPT
// === Index Usage Analysis ===
db.products.aggregate([{ $indexStats: {} }]);
// Find unused indexes

// === Index Usage in Slow Queries ===
db.system.profile.find({ millis: { $gt: 100 } })
  .sort({ ts: -1 })
  .limit(20)
  .forEach(profile => {
    console.log('Query:', profile.command.find);
    console.log('Plan:', profile.planSummary);
    console.log('Time:', profile.millis, 'ms');
  });

6. Ferramentas de monitoramento APM

Por que você precisa do APM? Os problemas em ambientes de produção não vêm com aviso prévio — picos repentinos de conexões, aumento no número de consultas lentas e vazamentos de memória ocorrem gradualmente. O APM (Monitoramento de Desempenho de Aplicações) oferece coleta de métricas em tempo real, painéis visuais e alertas de limite, permitindo que você identifique e resolva problemas antes que os usuários reclamem.

Pirâmide de métricas de monitoramento:

100%
graph TB
    L4[Business Metrics<br/>Orders/Error Rate/Response Time] --> L3[Application Metrics<br/>QPS/Latency/Node.js Memory]
    L3 --> L2[Database Metrics<br/>Number of connections/Slow Queries/Index Hit Rate]
    L2 --> L1[Infrastructure<br/>CPU/Memory/Disk/Internet]

    style L4 fill:#d4edda
    style L1 fill:#fff3cd

Indicadores-chave de desempenho:

Categoria da métrica Métrica específica Limite de alerta Método de coleta
Conexões Conexões atuais > maxPoolSize × 80% serverStatus.connections
Consulta Número de consultas lentas > 10/min system.profile
Consulta Tempo médio de consulta > 200 ms Mongoose Debug / APM
Índice Taxa de acertos do índice < 95% $indexStats
Memória Memória residente > 80% da RAM disponível serverStatus.mem
Disco Uso do disco > 80% db.stats()
Instância Atraso na replicação > 10 s rs.status().lag
Ferramenta Recursos Aplicações
Monitoramento do MongoDB Atlas Oficial, integrado Usuários do Atlas
Prometheus + mongo_exporter Código aberto, auto-hospedado Produção em grande escala
Datadog APM Comercial, Full-Stack Empresarial
New Relic Negócios, Full-Stack Corporativo
Prometheus + Grafana Código aberto, gratuito Monitoramento auto-hospedado

7. Lista de verificação para implantação em produção

Considerações importantes para ambientes de produção: A implantação em produção não se resume apenas a “garantir que o código funcione”; trata-se de assegurar alta disponibilidade (um único ponto de falha não afeta o serviço), segurança dos dados (sem perda ou vazamento de dados), observabilidade (a capacidade de identificar rapidamente os problemas) e capacidade de recuperação (a capacidade de restaurar a partir de backups).

Os Quatro Pilares da Implantação em Produção:

Pilar Objetivo Principais medidas
Alta disponibilidade Disponibilidade de 99,9% ou mais Conjunto de réplicas de 3 nós + failover automático
Segurança de dados Sem perda de dados + Sem vazamentos de dados Nível de garantia de gravação: maioria + TLS + RBAC
Observabilidade Identifique problemas em até 5 minutos Logs + Métricas + Alertas + APM
Capacidade de recuperação RPO < 1 h, RTO < 4 h Backups programados + PITR + Simulados de recuperação
MARKDOWN
## 10. Performance Optimization Checklist
---

### (1) Database
- [ ] Dungeon Collection 3 Node(High Availability)
- [ ] Write Concern majority(No data loss)
- [ ] Read Preference primaryPreferred
- [ ] Slow Query Monitoring Enabled
- [ ] Index Usage Monitoring
- [ ] Connection Pool maxPoolSize Settings

### (2) Application Layer
- [ ] mongoose lean() For read-only queries
- [ ] projection Search only the required fields
- [ ] bulkWrite Bulk Operations
- [ ] Avoid $where / $regex Unanchored
- [ ] Error-handling middleware
- [ ] Health Check Endpoints /healthz

### (3) Operations and Maintenance
- [ ] Daily mongodump Backup
- [ ] Backup Retention 7-30 days
- [ ] Monitoring Alerts(Number of connections / Slow Queries / Disk)
- [ ] TLS/SSL Encrypted Transmission
- [ ] SCRAM + RBAC Access Control
- [ ] Atlas PITR or oplog Continuous Backup

8. Prática: Ajuste abrangente de desempenho

Metodologia prática para ajuste de desempenho: O ajuste de desempenho não consiste em fazer otimizações baseadas em suposições; trata-se de um processo em ciclo fechado de “medir → analisar → otimizar → verificar”. Primeiro, use o explain() para medir o desempenho atual e identificar gargalos (varreduras completas de tabelas? Transferência excessiva de dados? Sobrecarga do Hydrate?), depois implemente otimizações direcionadas e, por fim, use o explain() novamente para verificar os resultados.

Ajuste de desempenho em circuito fechado:

100%
graph LR
    A[Measurement: explain + Slow Log] --> B[Analysis: Bottleneck Identification]
    B --> C[Optimization: Index/Projection/lean]
    C --> D[Verify: use explain again]
    D -->|Did not meet the standard| A
    D -->|Meet the requirements| E[Launch ✅]

    style A fill:#cce5ff
    style C fill:#d4edda
    style E fill:#d4edda

Estudo de caso de otimização do ShopHub: Alice, da TechCorp, otimizou a API da lista de produtos, reduzindo o tempo de resposta de 3 segundos para 50 ms — ① explain() revelou um COLLSCAN → adicionou um índice composto {category:1, isActive:1, createdAt:-1}; ② Retornava todos os campos → utilizou select() para consultar apenas 5; ③ Retornava um documento Mongoose → adicionou lean(); ④ find e count eram sequenciais → utilizou Promise.all para processamento paralelo.

JAVASCRIPT
// === Slow Queries Before Optimization ===
app.get('/api/products', async (req, res) => {
  const products = await Product.find({ isActive: true });
  // 100 Full-Table Scan of 10,000 Documents, ~3 seconds
  res.json(products);
});

// === After optimization ===
app.get('/api/products', async (req, res) => {
  const { page = 1, limit = 20, category, search } = req.query;

  // 1. Building Indexes to Optimize Queries
  const query = { isActive: true };
  if (category) query.category = category;
  if (search) query.title = new RegExp(search, 'i');

  // 2. Projection + lean + limit
  const products = await Product.find(query)
    .select('sku title price thumbnail')  // Projection
    .hint({ isActive: 1, category: 1 })  // Forced Index
    .limit(Math.min(+limit, 100))  // Maximum Limit
    .skip((+page - 1) * +limit)
    .lean();  // Performance Optimization

  // 3. Parallel count
  const total = await Product.countDocuments(query);

  res.json({ data: products, meta: { page: +page, limit: +limit, total } });
});
// After optimization:~50ms(Performance ↑60x)

▶ Exemplo 1: Diagnósticos do explain() + Otimização de índices

JAVASCRIPT
// === Scenario: ShopHub product list queries are slow, Alice uses explain to diagnose ===

// 1. Diagnose the Current Query
const explain = await Product.find({ category: 'Electronics', isActive: true })
  .sort({ createdAt: -1 })
  .limit(20)
  .explain('executionStats');

console.log('Stage:', explain.queryPlanner.winningPlan.stage);
// Output:COLLSCAN ❌ Full Table Scan!

console.log('Docs examined:', explain.executionStats.totalDocsExamined);
// Output:1000000(Scanned all of them 100 10,000 Documents)

console.log('Docs returned:', explain.executionStats.nReturned);
// Output: 20 (Returned only 20 docs)

console.log('Time:', explain.executionStats.executionTimeMillis, 'ms');
// Output: 3200ms (too slow!)

// 2. Create a composite index
db.products.createIndex({ category: 1, isActive: 1, createdAt: -1 });

// 3. Once again explain Verification
const explain2 = await Product.find({ category: 'Electronics', isActive: true })
  .sort({ createdAt: -1 })
  .limit(20)
  .hint({ category: 1, isActive: 1, createdAt: -1 })
  .explain('executionStats');

console.log('Stage:', explain2.queryPlanner.winningPlan.stage);
// Output:IXSCAN ✅ Using Indexes!

console.log('Docs examined:', explain2.executionStats.totalDocsExamined);
// Output:20(Precise Scanning)

console.log('Time:', explain2.executionStats.executionTimeMillis, 'ms');
// Output:5ms(↑640x Performance Improvements!)

Resultado: O diagnóstico explain() identificou um COLLSCAN → criou um índice composto → IXSCAN, e o tempo de execução da consulta caiu de 3.200 ms para 5 ms.

▶ Exemplo: Query Performance Diagnosis com explain() (Difficulty ⭐⭐)

JAVASCRIPT
// Scene: ShopHub slow product search diagnosis - is the index being used?
const mongoose = require('mongoose');
const Product = mongoose.model('Product');

async function diagnoseQuery() {
  // Step 1: Run query with explain
  const explanation = await Product.find({
    category: 'Electronics',
    price: { $gte: 100, $lte: 1000 }
  })
  .sort({ price: -1 })
  .explain('executionStats');
  
  const stats = explanation.executionStats;
  
  console.log('=== Query Performance Report ===');
  console.log(`Execution Time: ${stats.executionTimeMillis} ms`);
  console.log(`Documents Examined: ${stats.totalDocsExamined}`);
  console.log(`Documents Returned: ${stats.nReturned}`);
  console.log(`Index Used: ${stats.winningPlan.inputStage?.indexName || 'COLLSCAN'}`);
  
  // Step 2: Check for problems
  const problems = [];
  
  if (stats.executionTimeMillis > 100) {
    problems.push('Slow query (>100ms)');
  }
  
  if (stats.totalDocsExamined > stats.nReturned * 10) {
    problems.push(`High scan ratio: ${stats.totalDocsExamined}/${stats.nReturned}`);
  }
  
  if (!stats.winningPlan.inputStage?.indexName) {
    problems.push('No index used (COLLSCAN)');
  }
  
  // Step 3: Suggest fix
  if (problems.length > 0) {
    console.log('\n⚠️ Problems detected:');
    problems.forEach(p => console.log(`  - ${p}`));
    console.log('\n💡 Suggested index:');
    console.log('  ProductSchema.index({ category: 1, price: -1 })');
  } else {
    console.log('\n✅ Query performance is good');
  }
}

diagnoseQuery();

Saída:

TEXT 📖 Somente leitura
=== Query Performance Report ===
Execution Time: 245 ms
Documents Examined: 50000
Documents Returned: 120
Index Used: undefined

⚠️ Problems detected:
  - Slow query (>100ms)
  - High scan ratio: 50000/120
  - No index used (COLLSCAN)

💡 Suggested index:
  ProductSchema.index({ category: 1, price: -1 })

▶ Exemplo 2: Guia prático para otimização abrangente de desempenho (pool de conexões + indexação + otimização + monitoramento)

JAVASCRIPT
// === Scene:Product List API Performance Optimization(3s → 50ms)===

// === Before Optimization (slow) ===
app.get('/api/products', async (req, res) => {
  const products = await Product.find();  // Full Table Scan + Return all fields
  res.json(products);
});
// 100 10,000 Documents,~3000ms,~50MB Data

// === After optimization (fast) ===

// 1. Enable mongoose debug(Monitoring Queries During Development)
mongoose.set('debug', (coll, method, query) => {
  console.log(`${coll}.${method}(${JSON.stringify(query)})`);
});

// 2. Optimizing the Connection Pool
mongoose.connect(uri, {
  maxPoolSize: 50,         // Adjust Based on Concurrency
  minPoolSize: 5,
  maxIdleTimeMS: 30000,
  waitQueueTimeoutMS: 10000
});

// 3. Enable the slow query log(>100ms)
mongoose.connection.db.admin().command({
  setParameter: 1,
  slowms: 100
});

// 4. Create Appropriate Indexes
db.products.createIndex({ category: 1, isActive: 1, createdAt: -1 });
db.products.createIndex({ sku: 1 }, { unique: true });
db.products.createIndex({ title: 'text', description: 'text' });

// 5. Optimize Queries:projection + lean + hint + limit
app.get('/api/products', async (req, res) => {
  const { page = 1, limit = 20, category, search } = req.query;

  const query = { isActive: true };
  if (category) query.category = category;
  if (search) query.title = new RegExp(search, 'i');

  const [products, total] = await Promise.all([
    Product.find(query)
      .select('sku title price thumbnail rating')  // Projection:Return only 5 field
      .hint({ category: 1, isActive: 1, createdAt: -1 })  // Forced Index
      .sort({ createdAt: -1 })
      .skip((page - 1) * limit)
      .limit(Math.min(+limit, 100))
      .lean(),  // Skip mongoose hydrate
    Product.countDocuments(query)
  ]);

  res.json({
    success: true,
    data: products,
    meta: { page: +page, limit: +limit, total, pages: Math.ceil(total / limit) }
  });
});
// 100 10,000 Documents,~50ms(Performance ↑60x),~200KB Data(Reduce 99.6%)

// === 6. explain() Verify that the index is active ===
const explain = await Product.find({ category: 'Electronics', isActive: true })
  .sort({ createdAt: -1 })
  .limit(20)
  .explain('executionStats');

console.log('Stage:', explain.queryPlanner.winningPlan.stage);
// Output:IXSCAN(An index was used)

console.log('Docs examined:', explain.executionStats.totalDocsExamined);
console.log('Keys examined:', explain.executionStats.totalKeysExamined);
console.log('Returned:', explain.executionStats.nReturned);
console.log('Time:', explain.executionStats.executionTimeMillis, 'ms');

// === 7. Monitoring Alerts ===
// 7.1 Monitor Connection Count
const connStatus = await mongoose.connection.db.admin().command({ serverStatus: 1 });
if (connStatus.connections.current > 1000) {
  console.warn(`⚠️  Too many connections: ${connStatus.connections.current}`);
  // Send an Alert (Email/DingTalk/Slack)
}

// 7.2 Monitoring Slow Queries
const slowQueries = await mongoose.connection.db.collection('system.profile')
  .find({ millis: { $gt: 100 } })
  .sort({ ts: -1 })
  .limit(10)
  .toArray();

slowQueries.forEach(q => {
  console.log(`[${q.ts}] ${q.command.find}: ${q.millis}ms`);
  console.log(`  Plan: ${q.planSummary}`);
});

// 7.3 Index Usage Rate
const indexStats = await mongoose.connection.db.collection('products')
  .aggregate([{ $indexStats: {} }])
  .toArray();

const unused = indexStats.filter(s => s.accesses.ops === 0);
unused.forEach(i => {
  console.log(`⚠️  Index not used: ${i.name}`);
  // Automatic Deletion(Caution in Production Environments)
  // await mongoose.connection.db.collection('products').dropIndex(i.name);
});

// === 8. APM Integration(Datadog/New Relic)===
const tracer = require('dd-trace').init();
tracer.use('mongoose', { service: 'shopdb' });
// All mongoose Query Auto-Tracking,Performance Data Reporting Datadog

Resultados: Por meio de uma otimização abrangente do pool de conexões, dos índices, do Lean e das projeções, o desempenho das consultas melhorou de 3 segundos para 50 milissegundos (um aumento de 60 vezes), e a transferência de dados foi reduzida em 99,6%.

❓ Perguntas Frequentes

P: Um valor maior para maxPoolSize é sempre melhor? R: Não. Definir um valor muito alto esgotará as conexões do banco de dados (o valor padrão de maxIncomingConnections do MongoDB é 65536).

P: Quais são os efeitos colaterais do lean()? R: Você perde o acesso aos métodos de documento do Mongoose (como save e populate). Ele foi projetado para ser usado com a API exclusiva para consultas.

P: Como posso saber se uma consulta está usando um índice? R: query.explain('executionStats') Verifique a fase: IXSCAN (varredura por índice) / COLLSCAN (varredura completa da tabela).


📖 Resumo


📝 Exercícios

  1. Problema básico (⭐): Use lean() para otimizar a API da lista de produtos e comparar as diferenças de desempenho.
  2. Questão básica (⭐): Ative o log de consultas lentas e analise as 10 consultas mais lentas.
  3. Problema avançado (⭐⭐): Use uma dica para forçar a indexação e compare o desempenho do COLLSCAN e do IXSCAN.
  4. Problema avançado (⭐⭐): Analise $indexStats para identificar índices não utilizados e excluí-los.
  5. Desafio (⭐⭐⭐): Realize um ajuste abrangente de desempenho (pool de conexões + índices + otimização + monitoramento) e compare o desempenho antes e depois.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%