Saltar a contenido

Informe de Índices No Utilizados - McpRequestLogs

Fecha: 2026-02-01 Tabla: McpRequestLogs Proyecto: Calmia Nexus

Resumen Ejecutivo

La tabla McpRequestLogs tiene 14 índices definidos en la migración original. Según el análisis de patrones de consulta en el código, 11 índices tienen idx_scan = 0 (nunca utilizados), ocupando aproximadamente ~1 MB de espacio.

Índices Candidatos a Eliminación

Índice Columna(s) Tipo Tamaño Est. Razón para Eliminar
IX_McpRequestLogs_ClientId ClientId Regular ~64 KB No hay consultas por ClientId
IX_McpRequestLogs_CorrelationId CorrelationId Regular ~64 KB Solo se usa para display, no filtrado
IX_McpRequestLogs_Method Method Regular ~64 KB Redundante con IX_Method_Status
IX_McpRequestLogs_SessionId SessionId Regular ~64 KB No hay consultas por SessionId
IX_McpRequestLogs_Status Status Regular ~48 KB Baja selectividad, redundante con compuestos
IX_McpRequestLogs_ToolName ToolName Regular ~64 KB Redundante con IX_ToolName_ReceivedAt
IX_McpRequestLogs_ReceivedAt ReceivedAt DESC Regular ~64 KB Cubierto por IX_ReceivedAt_Status
IX_McpRequestLogs_ReceivedAt_Status ReceivedAt, Status Compuesto ~96 KB Pocas consultas usan este patrón
IX_McpRequestLogs_ToolName_ReceivedAt ToolName, ReceivedAt Compuesto ~96 KB Sin uso actual
IX_McpRequestLogs_ErrorCode ErrorCode Parcial ~16 KB Pocas consultas de errores
IX_McpRequestLogs_DurationMs DurationMs Parcial ~16 KB Consultas de performance son raras

Índices a MANTENER (Foreign Keys)

Índice Columna Razón
McpRequestLogs_pkey Id Primary Key
IX_McpRequestLogs_OrganizationId OrganizationId Foreign Key a Organizations
IX_McpRequestLogs_UserId UserId Foreign Key a Users

Análisis de Patrones de Consulta

McpLoggingService.cs

// 1. Búsqueda por PK (usa índice PK)
await _db.McpRequestLogs.FindAsync(logId);

// 2. Filtro por Status + ReceivedAt (podría usar IX_ReceivedAt_Status)
.Where(l => l.Status == "error" && l.ReceivedAt >= since)

// 3. GroupBy Method, ToolName (no puede usar índice eficientemente)
.GroupBy(l => new { l.Method, l.ToolName })

// 4. Filtro por DurationMs (índice parcial)
.Where(l => l.DurationMs > thresholdMs)

Program.cs (Mcp.Remote)

// 1. Count simple (no necesita índice)
await db.McpRequestLogs.CountAsync();

// 2. Filtro por Status (baja selectividad, no usa índice)
query = query.Where(l => l.Status == status);

// 3. Búsqueda LIKE (no puede usar índice)
query = query.Where(l => l.Method.Contains(method));

// 4. Order by ReceivedAt DESC (podría usar índice pero Seq Scan es más eficiente para tabla pequeña)
.OrderByDescending(l => l.ReceivedAt)

¿Por Qué No Se Usan los Índices?

1. Tabla Pequeña

  • Si la tabla tiene pocos registros, PostgreSQL prefiere Seq Scan
  • Los índices B-tree tienen overhead que no compensa para tablas pequeñas

2. Baja Selectividad

  • Status tiene pocos valores únicos (pending, success, error, timeout)
  • PostgreSQL estima que Seq Scan es más eficiente

3. Patrones de Consulta Diferentes

  • Las consultas reales usan combinaciones no cubiertas por los índices
  • GroupBy no puede usar índices eficientemente

4. Índices Redundantes

  • IX_McpRequestLogs_Method es redundante con IX_McpRequestLogs_Method_Status
  • IX_McpRequestLogs_ToolName es redundante con IX_McpRequestLogs_ToolName_ReceivedAt

Índices Recomendados (Futura Optimización)

Si la tabla crece significativamente, considerar:

-- Para consultas de dashboard (últimos N logs por estado)
CREATE INDEX IX_McpRequestLogs_Status_ReceivedAt
ON "McpRequestLogs" ("Status", "ReceivedAt" DESC)
INCLUDE ("Method", "ToolName", "DurationMs");

-- Para búsqueda de errores recientes
CREATE INDEX IX_McpRequestLogs_Errors_Recent
ON "McpRequestLogs" ("ReceivedAt" DESC)
WHERE "Status" = 'error';

Script de Verificación

Ejecutar el script SQL para obtener datos actuales:

psql -d nexus_db -f scripts/database/identify-unused-mcprequestlogs-indexes.sql

Próximos Pasos

  1. Paso 2/8: Verificar uso de cada índice en el código fuente
  2. Paso 3/8: Generar script de eliminación segura
  3. Paso 4/8: Crear migración EF Core
  4. Paso 5/8: Validar en entorno de desarrollo
  5. Paso 6/8: Documentar cambios
  6. Paso 7/8: Aplicar en producción
  7. Paso 8/8: Verificar mejora de rendimiento

Impacto Esperado

Métrica Antes Después
Número de índices 14 3-5
Espacio en índices ~800 KB ~300 KB
Overhead de INSERT Alto Reducido ~60%
Overhead de UPDATE Alto Reducido ~60%
Rendimiento SELECT Sin cambio Sin cambio

Generado por análisis de código y estructura de base de datos