Introducción
Un paso a paso para que abras, uses y valides la nueva pantalla Profiler. Sigue desde el Paso 1 hasta el final, en orden. Cada paso indica qué hacer y qué vas a ver. No necesitas saber nada de profiling de antemano — las cajas 💡 explican los conceptos en el momento en que aparecen.
Cómo leer este manual
Cada paso tiene:
- Hacer — la acción exacta (clic, escribir, ejecutar tal script).
- Ver — lo que debe ocurrir en la pantalla. Es tu “pasó / no pasó”.
- Por qué — solo cuando ayuda a entender (puedes saltarlo si tienes prisa).
Concepto
Caja de concepto. Explica un término en el momento en que aparece.
Atención
Atención. Un detalle que suele confundir.
Antes de empezar
Concepto
Qué es el Profiler
MongoDB puede registrar una “bitácora” de todo lo que ejecuta — cada consulta, cuánto tardó, si usó índice — en una colección llamada system.profile. La pantalla Profiler activa esa bitácora y la muestra de forma gráfica: gráficos, filtros e incluso recomendaciones de índice.
Vas a necesitar:
- 1El dev server reiniciado después del último build (sin esto la pantalla ni siquiera carga — es lo que causa el error
spacingPx). - 2Una conexión MongoDB conectada. Puede ser local, on-prem o Atlas M10+. En Atlas M0/M2/M5 (gratuito) el profiler está bloqueado por MongoDB — funciona, pero la pantalla avisará que está restringido (lo probamos en el Paso 41).
- 3El usuario de la base de datos debe poder ejecutar comandos de administración (
setProfilingLevel,createIndex). Un usuario “dueño de la base de datos” resuelve esto.
Tiempo estimado del recorrido completo: ~30 minutos.
Preparar la base de datos de laboratorio
Para que el Profiler tenga algo que mostrar, primero creamos una base de datos con bastantes datos.
Crear la base de datos profiler_lab
Abre la pestaña Mongo Shell (o el Scratchpad) de NoSqlStudio, pega el script de abajo y ejecútalo.
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,
}));El shell imprime, después de algunos segundos:
orders: 120000
products: 20000
customers: 5000120 mil pedidos es suficiente para que una consulta sin índice se vuelva visiblemente lenta — y la lentitud es exactamente lo que queremos diagnosticar.
Atención
Si más adelante las consultas no superan los 100 ms (máquina rápida), vuelve aquí y cambia 120000 por 300000.
Abrir la pantalla Profiler
Abrir por primera vez
Abre el Profiler de una de estas 3 maneras (todas llevan al mismo lugar — prueba las otras dos más tarde, en el Paso 46):
- Menú principal → Database Profiler, o el atajo Ctrl+Alt+Shift+P.
- Barra de herramientas → menú Monitoring → Database Profiler.
- Haz clic con el botón derecho en una conexión de la barra lateral → Profiler.
Se abre una nueva pestaña llamada Profiler, con el nombre de la conexión al lado. La pestaña tiene, de arriba abajo: una barra de cabecera, una franja de control y cuatro botones de sección (Dashboard, Live Feed, Index Advisor, Sessions).
Elegir la base de datos
En la cabecera, en el campo Database, elige `profiler_lab`.
La pantalla pasa a trabajar sobre esa base de datos. Como aún no activamos el profiling, el Dashboard muestra un mensaje del tipo “Sin datos de profiling todavía”.
Atención
El profiler es por base de datos. Todo este manual usa profiler_lab. Si eliges otra base de datos, no verás las pruebas.
Activar el profiling
Entender la franja de control
Justo debajo de la cabecera hay una franja con:
- Profiling — tres botones:
Off·Slow ops·All ops. - slowms y Sample — dos campos numéricos + botón Apply.
- Filtro — abre un constructor de filtro.
- ⏱ Captura — captura cronometrada segura.
- system.profile — una pequeña barra de uso de la colección + botón Resize.
- Estado — una nota (A–F) con puntuación.
Concepto
Los tres niveles. Off = no graba nada. Slow ops = graba solo lo que superó el límite slowms. All ops = graba todo. Para probar, vamos con All ops para ver todo el movimiento.
Activar en el nivel “All ops”
Haz clic en el botón All ops.
- El punto de estado a la izquierda se pone azul.
- Aparece una píldora de aviso “⚠ Todas las ops” (recordatorio de que el nivel 2 tiene un costo de rendimiento).
- Un mensaje rápido confirma “Profiling level set to 2”.
Este es el corazón de la herramienta. En el profiler antiguo esto solo copiaba un comando para que lo pegaras en el shell. Ahora el clic activa el profiling de verdad. Si el punto se puso azul, el camino técnico principal funcionó. ✅
Generar movimiento (las “pruebas”)
Ahora vamos a ejecutar consultas en el shell para que el Profiler tenga algo que mostrar. Mantén la pestaña Profiler abierta — se actualiza sola cada pocos segundos.
Prueba A — consultas lentas
Ejecuta en el shell:
use profiler_lab;
db.orders.find({ status: 'shipped' }).toArray().length;
db.orders.find({ region: 'south' }).sort({ total: -1 }).toArray().length;En 1–3 segundos, en la sección Live Feed, dos líneas nuevas de operación query en profiler_lab.orders, con un sello rojo COLLSCAN.
Concepto
COLLSCAN vs IXSCAN. COLLSCAN = MongoDB leyó documento por documento porque no había índice — lento. IXSCAN = usó un índice (un atajo) — rápido. Sello rojo = malo; sello azul = bueno.
Prueba B — consulta ineficiente
Ejecuta en el shell:
use profiler_lab;
db.orders.find({ status: 'refunded', region: 'north', items: 7 }).toArray();Una línea más en el feed. En la columna Examined → Returned el número queda en rojo — examinó 120 mil documentos para devolver unos pocos.
Concepto
Ineficiente. Cuando la base de datos “examina” mucho más de lo que “retorna”, está desperdiciando trabajo — es una fuerte candidata a recibir un índice.
Prueba C — escrituras
Ejecuta en el 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 });Tres operaciones nuevas: insert, update, remove.
Pruebas D, E, F — agregación, conteo y cursores
Ejecuta en el 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);Operaciones de los tipos command (la agregación, el conteo) y varias getmore (el cursor que lee en lotes).
Prueba G — la misma consulta repetida
Ejecuta en el shell:
use profiler_lab;
for (let i = 0; i < 40; i++) db.orders.find({ status: 'paid' }).limit(10).toArray();Nada especial en el feed ahora — pero recuérdalo: en el Paso 24 esto se convierte en una sola línea en el panel de “Query shapes”, con conteo 40.
Explorar el Live Feed
Abrir el feed
Haz clic en la sección Live Feed (en la parte superior).
Una tabla con las operaciones, la más reciente arriba. Columnas: hora, tipo, colección, duración (coloreada — verde rápido, rojo lento), plan (sello COLLSCAN/IXSCAN), examinados→retornados, y app. En la parte superior, “X de Y operaciones”.
Ver el modo en vivo funcionando
Ejecuta de nuevo la Prueba A (la del Paso 6) y mantén la vista en el feed:
use profiler_lab;
db.orders.find({ status: 'shipped' }).toArray().length;
db.orders.find({ region: 'south' }).sort({ total: -1 }).toArray().length;Las líneas nuevas aparecen solas en la parte superior en segundos.
Pausar y reanudar
En la cabecera, haz clic en el botón ● Live (se convierte en ⏸ Pausado). Ejecuta la Prueba A de nuevo:
use profiler_lab;
db.orders.find({ status: 'shipped' }).toArray().length;
db.orders.find({ region: 'south' }).sort({ total: -1 }).toArray().length;El feed no crece — está congelado. Haz clic en ⏸ Pausado para volver a ● Live: vuelve a crecer.
Pausar es útil para inspeccionar una línea sin que la lista esté saltando.
Filtros rápidos (los chips de preset)
Haz clic, uno a la vez, en los chips de la parte superior del feed:
- Lentas > 100ms — solo operaciones lentas.
- COLLSCANs — solo las sin índice (sello rojo).
- Ineficientes — destaca la del Paso 7.
- Writes — solo insert/update/remove (las del Paso 8).
- Últimos 5 min — solo el movimiento reciente.
La tabla se reduce para mostrar solo lo que coincide. El chip activo queda destacado. Haz clic de nuevo para desactivarlo.
Filtros finos
Haz, en secuencia:
- 1Haz clic en los chips de tipo (
query,insert,getmore…) para activar/desactivar. - 2En el desplegable Todas las colecciones, elige
orders. - 3En la búsqueda, escribe
refunded.
Cada filtro acota la lista. Se combinan entre sí.
Limpiar todo
Haz clic en Limpiar filtros (aparece cuando hay un filtro activo).
La tabla vuelve a mostrar todo.
Explorar el Dashboard
Abrir el Dashboard
Haz clic en la sección Dashboard.
Cuatro tarjetas de número en la parte superior (Operaciones, Ops lentas, Recorridos de colección, Duración media) y, debajo, varios gráficos.
Los indicadores (KPIs)
Los cuatro números reflejan todo lo que provocaste. “Recorridos de colección” muestra el porcentaje de COLLSCANs — cuanto más alto, peor.
Línea de tiempo
El gráfico Operaciones a lo largo del tiempo muestra franjas apiladas por tipo (lecturas, inserts, updates, deletes, comandos), con leyenda coloreada.
Uso de índices (anillo)
El gráfico de anillo Uso de índices divide las operaciones en COLLSCAN (rojo), IXSCAN (azul) y otras. Hoy debería estar dominado por el rojo.
Distribución de latencia
Barras que agrupan las operaciones por franja de tiempo (0–1ms, …, >5s).
Colecciones más calientes (treemap)
Bloques proporcionales al tiempo total gastado en cada colección. orders debería ser el bloque más grande.
Hacer clic en un bloque del treemap
Haz clic en el bloque orders.
La pantalla salta al Live Feed ya filtrado por orders. (Vuelve al Dashboard después.)
Formas de consulta (query shapes)
La tabla Query shapes agrupa consultas con el mismo “formato”. La consulta que repetiste 40× en el Paso 10 aparece como una sola línea, con conteo 40 y el tiempo sumado.
Así es como descubres “qué consulta, sumando todas las veces, pesa más en la base de datos” — aunque cada ejecución individual sea rápida.
Operaciones más lentas
La tabla final lista las 8 operaciones más lentas. Guárdala para el siguiente paso.
Investigar una operación (drill-down)
Abrir el panel de detalle
Haz clic en cualquier línea — en el Live Feed, en la tabla de query shapes o en la de más lentas.
Un panel se desliza desde la derecha con el detalle completo de la operación.
Leer los números
Una cuadrícula con Duración, Plan, Yields, Docs examinados, Claves examinadas, Retornados. Si la operación es ineficiente, un aviso rojo indica que es una “fuerte candidata a índice”.
Pedir el “explain” en vivo
Haz clic en Explicar esta consulta.
La herramienta ejecuta el explain() en el momento y muestra el plan real, el tiempo de ejecución y cuántos documentos se examinaron — útil para confirmar el diagnóstico en la base de datos actual.
Concepto
Explain. Es MongoDB describiendo cómo pretende ejecutar la consulta. Confirma si usaría índice o no.
Ver el comando y los detalles
En el panel, mira la sección Comando (el JSON de la operación) y haz clic en el icono de copiar. Después haz clic en Execution stats y Documento sin procesar para expandir/contraer.
El comando se copia al portapapeles; las secciones se abren y se cierran.
Cerrar el panel
Ciérralo con la X de la parte superior del panel — y abre otro y ciérralo haciendo clic en el área oscurecida al lado.
El panel desaparece de las dos formas.
Usar el Index Advisor (lo destacado)
Generar recomendaciones
Ejecuta en el shell (son 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();
}Espera unos segundos. (Continúa en el siguiente paso.)
Abrir el Index Advisor
Haz clic en la sección Index Advisor.
En la parte superior, una tarjeta de Estado con una nota (A–F) — probablemente baja (C/D), porque generaste muchos COLLSCANs. Debajo, una lista de recomendaciones de índice — cerca de 3 tarjetas.
Leer una recomendación
Cada tarjeta tiene: una píldora de severidad (Alta/Media/Baja), la colección, el “formato” de la consulta, chips con los campos del índice sugerido (con flechas ↑/↓) y una línea de impacto (“N operaciones · X s en total · M recorridos”).
Concepto
Por qué esos campos en ese orden. El advisor sigue la regla ESR: campos de igualdad primero, después los de ordenación, después los de rango. Es el orden que hace que el índice sea más eficiente.
Crear un índice con 1 clic
En una tarjeta, haz clic en Crear índice. Revisa el comando en el modal y confirma.
Un mensaje “Índice creado”. La tarjeta de esa recomendación cambia a ✓ Ya indexado.
Crear los demás
Repite el Paso 34 para las demás recomendaciones.
Todas pasan a ✓ Ya indexado.
Confirmar que mejoró
Ejecutar las mismas consultas de nuevo
Ejecuta otra vez el mismo script del Paso 31 (repetido aquí para que no tengas que volver):
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();
}Las consultas se ejecutan de nuevo — ahora con los índices que creaste en la Etapa 8 ya en vigor.
Ver el COLLSCAN convertirse en IXSCAN
Ve al Live Feed.
Las mismas consultas ahora aparecen con sello azul IXSCAN y duración mucho menor. Antes leían 120 mil documentos; ahora usan el índice.
Ver subir la nota de Estado
Vuelve al Index Advisor (o haz clic en la píldora Estado del panel de control).
La nota subió (ej.: de C/D a A/B) y hay menos recomendaciones. Acabas de completar un ciclo completo: diagnosticar → corregir → comprobar. ✅
Sesiones e informe
Concepto
Sesión. Una “foto” del estado actual del profiling, guardada con un nombre. Sirve para comparar “antes” y “después” de un cambio.
Guardar una sesión
Ve a Sessions, escribe un nombre (ej.: depois dos indices) y haz clic en Guardar sesión.
La sesión aparece en la lista, con sus indicadores y la fecha.
Comparar
En la lista, selecciona dos entradas — por ejemplo la sesión guardada y la Ventana actual (que está siempre en la parte superior).
Aparece una tabla de Comparación con la columna Δ coloreada — verde cuando mejoró (menos COLLSCAN, menos tiempo), rojo cuando empeoró.
Exportar el informe
Haz clic en Exportar informe.
Descarga un archivo .json con el estado, las recomendaciones, las formas de consulta y las operaciones más lentas — para adjuntar a un ticket o guardar.
Funciones de control y seguridad
Captura cronometrada segura
Concepto
Por qué existe. Dejar el nivel 2 activado y olvidarlo es peligroso en producción. La “captura” activa el nivel 2, hace una cuenta regresiva y se desactiva sola al final.
En la franja de control, haz clic en ⏱ Captura y elige 30s. Durante esos 30s, ejecuta una prueba cualquiera — por ejemplo la Prueba A:
use profiler_lab;
db.orders.find({ status: 'shipped' }).toArray().length;
db.orders.find({ region: 'south' }).sort({ total: -1 }).toArray().length;El profiling pasa al nivel 2 y aparece una píldora con la cuenta regresiva. Al llegar a cero, el nivel vuelve solo a lo que estaba antes, con el mensaje “Captura concluida”. (También puedes hacer clic en Cancelar para terminar antes.)
Filtro de profiling
Haz clic en Filtro, rellena Namespace con orders y haz clic en Aplicar filtro. A continuación ejecuta la Prueba A:
use profiler_lab;
db.orders.find({ status: 'shipped' }).toArray().length;
db.orders.find({ region: 'south' }).sort({ total: -1 }).toArray().length;Después haz clic en Filtro → Limpiar filtro.
Con el filtro activo, solo se graban operaciones en orders (y el botón muestra “Filtro activo”). Al limpiarlo, vuelve a grabar todo.
Gestionar la colección system.profile
Concepto
Capped collection. La bitácora del profiler tiene un tamaño fijo; cuando se llena, borra lo más antiguo. El valor por defecto (1 MB) se llena rápido.
Observa la pequeña barra system.profile en la franja de control (muestra usado / total). Haz clic en Resize, elige 10 MB y confirma.
La barra pasa a reflejar ~/10 MB. El modal avisa que el historial actual se borra al redimensionar.
Ajustar slowms y la tasa de muestreo
Cambia slowms a 50 y haz clic en Apply. Después haz clic en Slow ops y ejecuta la Prueba A:
use profiler_lab;
db.orders.find({ status: 'shipped' }).toArray().length;
db.orders.find({ region: 'south' }).sort({ total: -1 }).toArray().length;En el nivel “Slow ops” solo entran en el feed las operaciones más lentas que el slowms definido — las rápidas se ignoran.
Acabado
Otras maneras de abrir
Prueba los 3 puntos de entrada del Paso 2 que aún no usaste.
Todos abren la pestaña Profiler. Si ya hay una abierta, se enfoca la existente en lugar de duplicarla.
Idiomas
En Settings → Language, cambia el idioma (son 5). Vuelve al Profiler.
Toda la pantalla del Profiler aparece traducida — sin textos “crudos” tipo profiler.xyz.
Temas
Alterna el tema entre Light, Dark y Neon.
Colores, tarjetas y gráficos se adaptan; nada de texto invisible.
Limpieza (cuando termines)
Ejecuta en el shell:
use profiler_lab;
db.setProfilingLevel(0);
db.dropDatabase();El profiling se desactiva y la base de datos de laboratorio desaparece.
Resumen de lo que validaste
| Etapa | Funcionalidad |
|---|---|
| 2–3 | Abrir el Profiler (3 entradas) + elegir base de datos |
| 3 | Activar el profiling de verdad (Off / Slow / All) |
| 4–5 | Live Feed: tiempo real, pausar, presets, filtros, búsqueda |
| 6 | Dashboard: KPIs, línea de tiempo, anillo, latencia, treemap, query shapes |
| 7 | Drill-down: detalles, explain() en vivo, comando, raw |
| 8–9 | Index Advisor: recomendaciones, crear índice, comprobar la mejora |
| 10 | Sesiones: guardar, comparar, exportar informe |
| 11 | Captura cronometrada, filtro, resize, slowms |
| 12 | Entradas alternativas, 5 idiomas, 3 temas |