El mayor portal de MU Online de Brasil — desde 2003
Tutorial Avanzado Infra

Cómo diagnosticar una consulta SQL lenta específica en la base de datos de tu servidor de MU Online

Encuentra y corrige la consulta específica que está bloqueando la base de datos de tu servidor de MU Online, usando el plan de ejecución, índices y el Profiler/Extended Events de SQL Server.

BR Bruno · Actualizado el 31 jul 2026 · ⏱ 16 min de lectura
Respuesta rápida

Un servidor de MU Online puede tener el GameServer y el ConnectServer perfectamente saludables y aun así sufrir trabas visibles para el jugador: login demorado, ranking que se cuelga al abrir, lista de guild lenta, porque una sola consulta SQL mal optimizada está monopolizando la base de datos. A di

Un servidor de MU Online puede tener el GameServer y el ConnectServer perfectamente saludables y aun así sufrir trabas visibles para el jugador: login demorado, ranking que se cuelga al abrir, lista de guild lenta, porque una sola consulta SQL mal optimizada está monopolizando la base de datos. A diferencia de un problema de infraestructura genérico, este tipo de cuello de botella es quirúrgico: una consulta específica, ejecutándose con frecuencia, sin el índice correcto. Este tutorial enseña a identificar exactamente qué consulta es la culpable, entender por qué es lenta y corregirla sin romper el resto del sistema.

Síntomas típicos de una consulta lenta específica

La primera señal de que el problema es una consulta puntual (y no el servidor de base de datos entero) es la localización del síntoma: una acción específica del juego se traba (abrir ranking, entrar al juego, listar guild, procesar comercio) mientras el resto sigue fluido. Si todo está lento al mismo tiempo, el problema tiende a ser de recursos generales (CPU, disco, memoria de SQL Server); si una acción se traba y las demás siguen normales, el problema es una consulta específica compitiendo por recursos o atascada en un lock.

Herramientas de diagnóstico disponibles

HerramientaUsoCuándo usarla
SQL Server ProfilerCaptura consultas en tiempo real con duraciónDiagnóstico puntual, entorno de prueba
Extended EventsSustituto moderno del Profiler, más livianoProducción, captura continua sin gran impacto
Activity MonitorVista rápida de sesiones activas y esperasPrimer vistazo durante el incidente
DMVs (sys.dm_exec_query_stats)Estadísticas agregadas de consultas desde el último reinicioEncontrar la consulta más costosa históricamente
Plan de ejecución (Execution Plan)Muestra cómo SQL Server decidió buscar los datosDespués de identificar la consulta candidata

Paso 1 — Capturar la consulta en el momento del síntoma

Con Extended Events (recomendado en producción por tener menor overhead que el Profiler clásico), crea una sesión filtrando por duración mínima:

CREATE EVENT SESSION [SlowQueries] ON SERVER
ADD EVENT sqlserver.sql_statement_completed(
    ACTION(sqlserver.sql_text, sqlserver.client_hostname)
    WHERE duration > 1000000 -- 1 segundo, en microsegundos
)
ADD TARGET package0.event_file(SET filename = N'SlowQueries.xel');
GO
ALTER EVENT SESSION [SlowQueries] ON SERVER STATE = START;

Reproduce el síntoma en el juego (abre el ranking, haz login) y luego detén la sesión para analizar el archivo .xel en SQL Server Management Studio.

Paso 2 — Encontrar la consulta más costosa históricamente

Si el síntoma es intermitente y no pudiste capturarlo en vivo, usa las DMVs de estadísticas acumuladas:

SELECT TOP 20
    qs.total_elapsed_time / qs.execution_count AS avg_time_us,
    qs.execution_count,
    SUBSTRING(qt.text, qs.statement_start_offset/2 + 1,
      (CASE WHEN qs.statement_end_offset = -1
            THEN LEN(CONVERT(nvarchar(max), qt.text)) * 2
            ELSE qs.statement_end_offset END - qs.statement_start_offset)/2 + 1) AS query_text
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
ORDER BY avg_time_us DESC;

Esta consulta ordena por el tiempo promedio de ejecución; la candidata número 1 casi siempre es la misma consulta de la que se queja el jugador.

Paso 3 — Leer el plan de ejecución

Con la consulta identificada, solicita el plan de ejecución real (Include Actual Execution Plan en SSMS) y busca señales de alerta:

Elemento en el planQué significaAcción
Table Scan en tabla grandeNo se está usando ningún índiceCrear índice en la columna del WHERE/JOIN
Index Scan (no Seek)El índice existe pero no es lo bastante selectivoRevisar las columnas del índice
Ícono de advertencia amarilloEstimación de filas muy distinta de la realActualizar estadísticas (UPDATE STATISTICS)
Key Lookup repetidoEl índice cubre el filtro pero no las columnas devueltasCrear índice cubierto (INCLUDE)
Sort con costo altoORDER BY sin un índice que ya entregue el ordenÍndice en la columna de ordenamiento

Paso 4 — Casos clásicos en la base de datos de MU Online

Algunos patrones se repiten en prácticamente todo emulador (IGCN, MuEMU, X-Team):

  • Ranking general (SELECT TOP N ... ORDER BY Resets DESC): sin índice en la columna de Resets/nivel, SQL Server recorre toda la tabla de personajes cada vez que se abre el ranking. Un índice en la columna de ordenamiento resuelve la mayoría de los casos.
  • Login (SELECT * FROM MEMB_INFO WHERE memb___id = @id): debería ser instantáneo; si está lento, generalmente falta un índice (o incluso una clave primaria) en la columna de login, o la tabla tiene fragmentación alta.
  • Lista de guild / miembro de guild: joins entre la tabla de guild y la de personaje sin índice en la clave foránea generan un Table Scan doble.
  • Log de comercio/chat: las tablas de log crecen indefinidamente; sin índice ni rutina de limpieza, las consultas que revisan el historial reciente se vuelven cada vez más lentas con el tiempo.

Paso 5 — Crear el índice correcto

Después de identificar la columna candidata, crea un índice no clusterizado dirigido:

CREATE NONCLUSTERED INDEX IX_Character_Resets
ON Character (ResetCount DESC)
INCLUDE (CharacterName, Level, Class);

El INCLUDE evita el "Key Lookup" al entregar directamente las columnas que la consulta pide en el SELECT, sin necesidad de que formen parte de la clave de ordenamiento del índice.

Paso 6 — Validar la ganancia

Ejecuta la consulta nuevamente con SET STATISTICS TIME ON y SET STATISTICS IO ON antes y después de crear el índice, comparando logical reads y tiempo de CPU. Una mejora real suele reducir los logical reads en un orden de magnitud (de miles a decenas), no solo algunos milisegundos.

SET STATISTICS IO ON;
SET STATISTICS TIME ON;
-- ejecutar la consulta aquí

Parameter sniffing: cuando la misma consulta varía de rápida a lenta

Si la consulta a veces es rápida y a veces lenta con datos parecidos, el problema puede ser un plan de ejecución reutilizado para un parámetro atípico (parameter sniffing). Síntomas: la primera ejecución del día es lenta y luego rápida, o al revés. Soluciones comunes: OPTION (RECOMPILE) en la consulta específica (costo extra de CPU por ejecución, pero plan siempre adecuado), o reescribir el procedimiento con variables locales para forzar un plan más genérico.

Mantenimiento preventivo de índices y estadísticas

Los índices se fragmentan con el tiempo (los INSERT/UPDATE/DELETE constantes de un juego online generan esto rápidamente). Programa mantenimiento periódico:

-- Rebuild en índices con fragmentación alta (>30%)
ALTER INDEX ALL ON Character REBUILD;
-- Actualizar estadísticas para que el optimizador tenga datos correctos
UPDATE STATISTICS Character;

Ejecuta esto en una ventana de bajo movimiento (madrugada), nunca en horario de pico; un rebuild consume I/O y puede competir con el propio juego por los mismos recursos.

Errores comunes y soluciones

SíntomaCausa probableSolución
El ranking tarda varios segundos en abrirFalta de índice en la columna de ordenamientoCrear índice no clusterizado con INCLUDE
Login lento solo para algunos jugadoresFragmentación alta en la tabla de cuentaRebuild de índice y revisar la clave de búsqueda del login
Consulta rápida y lenta alternadamenteParameter sniffingOPTION (RECOMPILE) o reescribir con variable local
Todo lento al mismo tiempo, no solo una acciónProblema de recurso general, no de consultaVerificar CPU/disco/memoria del servidor de base de datos
El rendimiento empeora con el tiempo, sin cambio de códigoLog/historial creciendo sin limpieza ni índiceCrear rutina de archivado/purga e índice en la columna de fecha

Lista de verificación de diagnóstico de consulta lenta

  • Síntoma localizado en una acción específica del juego, no en todo el servidor.
  • Extended Events o DMV usado para capturar la consulta exacta.
  • Plan de ejecución analizado en busca de Table/Index Scan.
  • Índice creado en las columnas de filtro/ordenamiento identificadas.
  • Ganancia validada con STATISTICS IO/TIME antes y después.
  • Parameter sniffing descartado o tratado si la lentitud es intermitente.
  • Rutina de mantenimiento de índice/estadística programada para la madrugada.

Después de resolver la consulta puntual, vale la pena revisar la salud general de la base de datos y del GameServer como un todo para evitar que el próximo cuello de botella pase desapercibido; el tutorial de creación de servidor de MU Online cubre la configuración base que sostiene este tipo de mantenimiento.

Preguntas frecuentes

¿Cómo sé que el problema es una consulta y no el servidor de base de datos en general?

Si la CPU/disco del servidor de base de datos está normal pero un comando específico del juego se traba (login lento, ranking demorando, comercio trabado), el problema está localizado. Ejecuta el Activity Monitor o Extended Events durante el síntoma para aislar la consulta exacta antes de tocar el hardware.

¿Necesito saber SQL avanzado para usar el plan de ejecución?

Lo básico ya ayuda mucho: busca íconos de advertencia (amarillos) en el plan gráfico y operadores como Table Scan/Index Scan en tablas grandes; casi siempre indican falta de índice. No necesitas dominarlo todo para resolver los casos más comunes.

¿Crear un índice nuevo tiene algún riesgo?

Sí. Los índices aceleran la lectura pero cuestan en escritura (cada INSERT/UPDATE necesita actualizar el índice también) y ocupan espacio en disco. En tablas de alta escritura, como logs de conexión, evalúa el trade-off antes de crear índices en exceso.

¿Qué es el parameter sniffing y por qué a veces vuelve lenta la consulta?

Es cuando SQL Server reutiliza un plan de ejecución optimizado para un valor de parámetro específico, pero ese plan es malo para otros valores. La consulta 'a veces' es rápida y 'a veces' lenta con los mismos datos, lo que confunde el diagnóstico si no sabes buscar esto.

¿El rebuild de índice resuelve la lentitud automáticamente?

Ayuda cuando la causa es la fragmentación, pero no resuelve consultas mal escritas ni la ausencia de un índice adecuado. Ejecuta el rebuild como mantenimiento periódico, no como solución mágica para todo problema de rendimiento.

BR
Editor de eventos, mapas e ítems

Bruno es especialista en eventos, mapas, bosses y economía de ítems de MU Online. Documenta cada detalle basándose en el juego real.

Sigue leyendo

Artículos relacionados