O maior portal de MU Online do Brasil — desde 2003
Tutorial Avançado Infra

Como diagnosticar uma consulta SQL lenta específica no banco do seu servidor de MU Online

Encontre e corrija a query específica que está travando o banco de dados do seu servidor de MU Online, usando plano de execução, índices e o Profiler/Extended Events do SQL Server.

BR Bruno · Atualizado em 31 jul 2026 · ⏱ 16 min de leitura
Resposta rápida

Um servidor de MU Online pode ter GameServer e ConnectServer perfeitamente saudáveis e mesmo assim sofrer travamentos visíveis para o jogador — login demorado, ranking que trava ao abrir, guild list lenta — porque uma única query SQL mal otimizada está monopolizando o banco de dados. Diferente de um

Um servidor de MU Online pode ter GameServer e ConnectServer perfeitamente saudáveis e mesmo assim sofrer travamentos visíveis para o jogador — login demorado, ranking que trava ao abrir, guild list lenta — porque uma única query SQL mal otimizada está monopolizando o banco de dados. Diferente de um problema de infraestrutura genérico, esse tipo de gargalo é cirúrgico: uma consulta específica, rodando com frequência, sem o índice certo. Este tutorial ensina a identificar exatamente qual query é a culpada, entender por que ela é lenta e corrigi-la sem quebrar o resto do sistema.

Sintomas típicos de uma query lenta específica

O primeiro sinal de que o problema é uma query pontual (e não o servidor de banco inteiro) é a localização do sintoma: uma ação específica do jogo trava (abrir ranking, entrar no jogo, listar guild, processar trade) enquanto o resto continua fluido. Se tudo está lento ao mesmo tempo, o problema tende a ser recursos gerais (CPU, disco, memória do SQL Server); se uma ação trava e as outras seguem normais, o problema é uma query específica competindo por recursos ou travada em um lock.

Ferramentas de diagnóstico disponíveis

FerramentaUsoQuando usar
SQL Server ProfilerCaptura queries em tempo real com duraçãoDiagnóstico pontual, ambiente de teste
Extended EventsSubstituto moderno do Profiler, mais leveProdução, captura contínua sem impacto grande
Activity MonitorVisão rápida de sessões ativas e esperasPrimeira olhada durante o incidente
DMVs (sys.dm_exec_query_stats)Estatísticas agregadas de queries desde o último restartAchar a query mais custosa historicamente
Plano de execução (Execution Plan)Mostra como o SQL Server decidiu buscar os dadosDepois de identificar a query candidata

Passo 1 — Capturar a query no momento do sintoma

Com o Extended Events (recomendado em produção por ter overhead menor que o Profiler clássico), crie uma sessão filtrando por duração 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, em microssegundos
)
ADD TARGET package0.event_file(SET filename = N'SlowQueries.xel');
GO
ALTER EVENT SESSION [SlowQueries] ON SERVER STATE = START;

Reproduza o sintoma no jogo (abra o ranking, faça login) e depois pare a sessão para analisar o arquivo .xel no SQL Server Management Studio.

Passo 2 — Achar a query mais custosa historicamente

Se o sintoma é intermitente e você não conseguiu capturar ao vivo, use as DMVs de estatí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;

Essa query ordena pelo tempo médio de execução — a candidata número 1 quase sempre é a mesma query que o jogador reclama estar travando.

Passo 3 — Ler o plano de execução

Com a query identificada, peça o plano de execução real (Include Actual Execution Plan no SSMS) e procure sinais de alerta:

Elemento no planoO que significaAção
Table Scan em tabela grandeNão há índice sendo usadoCriar índice na coluna do WHERE/JOIN
Index Scan (não Seek)Índice existe mas não é seletivo o suficienteRevisar colunas do índice
Ícone de warning amareloEstimativa de linhas muito diferente do realAtualizar estatísticas (UPDATE STATISTICS)
Key Lookup repetidoÍndice cobre o filtro mas não as colunas retornadasCriar índice coberto (INCLUDE)
Sort com custo altoORDER BY sem índice que já entregue a ordemÍndice na coluna de ordenação

Passo 4 — Casos clássicos no banco de MU Online

Alguns padrões se repetem em praticamente todo emulador (IGCN, MuEMU, X-Team):

  • Ranking geral (SELECT TOP N ... ORDER BY Resets DESC): sem índice na coluna de Resets/level, o SQL Server varre a tabela de personagens inteira a cada abertura de ranking. Índice na coluna de ordenação resolve na maioria dos casos.
  • Login (SELECT * FROM MEMB_INFO WHERE memb___id = @id): deveria ser instantâneo; se está lento, geralmente falta índice (ou até chave primária) na coluna de login, ou a tabela está com fragmentação alta.
  • Guild list / guild member: joins entre tabela de guild e de personagem sem índice na chave estrangeira geram Table Scan duplo.
  • Log de trade/chat: tabelas de log crescem indefinidamente; sem índice e sem rotina de limpeza, queries que consultam histórico recente ficam cada vez mais lentas com o tempo.

Passo 5 — Criar o índice certo

Depois de identificar a coluna candidata, crie um índice não-clusterizado direcionado:

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

O INCLUDE evita o "Key Lookup" ao já entregar as colunas que a query pede no SELECT, sem precisar que elas façam parte da chave de ordenação do índice.

Passo 6 — Validar o ganho

Rode a query novamente com SET STATISTICS TIME ON e SET STATISTICS IO ON antes e depois de criar o índice, comparando logical reads e tempo de CPU. Uma melhora real costuma reduzir logical reads em uma ordem de grandeza (de milhares para dezenas), não apenas alguns milissegundos.

SET STATISTICS IO ON;
SET STATISTICS TIME ON;
-- rodar a query aqui

Parâmetro sniffing: quando a mesma query varia de rápida para lenta

Se a query às vezes é rápida e às vezes lenta com dados parecidos, o problema pode ser plano de execução reutilizado para um parâmetro atípico (parameter sniffing). Sintomas: primeira execução do dia lenta, depois rápida, ou o oposto. Soluções comuns: OPTION (RECOMPILE) na query específica (custo de CPU extra por execução, mas plano sempre adequado), ou reescrever a procedure com variáveis locais para forçar um plano mais genérico.

Manutenção preventiva de índices e estatísticas

Índices se fragmentam com o tempo (INSERT/UPDATE/DELETE constantes de um jogo online geram isso rapidamente). Agende manutenção periódica:

-- Rebuild em índices com fragmentação alta (>30%)
ALTER INDEX ALL ON Character REBUILD;
-- Atualizar estatísticas para o otimizador ter dados corretos
UPDATE STATISTICS Character;

Rode isso em janela de baixo movimento (madrugada), nunca em horário de pico — um rebuild consome I/O e pode competir com o próprio jogo pelos mesmos recursos.

Erros comuns e soluções

SintomaCausa provávelSolução
Ranking demora vários segundos para abrirFalta de índice na coluna de ordenaçãoCriar índice não-clusterizado com INCLUDE
Login lento só para alguns jogadoresFragmentação alta na tabela de contaRebuild de índice e checar chave de busca do login
Query rápida e lenta alternadamenteParameter sniffingOPTION (RECOMPILE) ou reescrever com variável local
Tudo lento ao mesmo tempo, não só uma açãoProblema de recurso geral, não de queryVerificar CPU/disco/memória do servidor de banco
Performance piora com o tempo, sem mudança de códigoLog/histórico crescendo sem limpeza nem índiceCriar rotina de arquivamento/purga e índice na coluna de data

Checklist de diagnóstico de query lenta

  • Sintoma localizado em uma ação específica do jogo, não no servidor todo.
  • Extended Events ou DMV usado para capturar a query exata.
  • Plano de execução analisado em busca de Table/Index Scan.
  • Índice criado nas colunas de filtro/ordenação identificadas.
  • Ganho validado com STATISTICS IO/TIME antes e depois.
  • Parameter sniffing descartado ou tratado se a lentidão for intermitente.
  • Rotina de manutenção de índice/estatística agendada para madrugada.

Depois de resolver a query pontual, vale revisar a saúde geral do banco e do GameServer como um todo para evitar que o próximo gargalo passe despercebido — o tutorial de criação de servidor de MU Online cobre a configuração de base que sustenta esse tipo de manutenção.

Perguntas frequentes

Como sei que o problema é uma query e não o servidor de banco em geral?

Se a CPU/disco do servidor de banco está normal mas um comando específico do jogo trava (login lento, ranking demorando, trade travando), o problema é localizado. Rode o Activity Monitor ou Extended Events durante o sintoma para isolar a query exata antes de mexer em hardware.

Preciso saber SQL avançado para usar o plano de execução?

O básico já ajuda muito: procure ícones de warning (amarelo) no plano gráfico e operadores como Table Scan/Index Scan em tabelas grandes — eles quase sempre indicam falta de índice. Você não precisa dominar tudo para resolver os casos mais comuns.

Criar um índice novo tem algum risco?

Sim. Índices aceleram leitura mas custam em escrita (todo INSERT/UPDATE precisa atualizar o índice também) e ocupam espaço em disco. Em tabelas de alta escrita, como logs de conexão, avalie o trade-off antes de criar índices em excesso.

O que é um parâmetro sniffing e por que ele deixa a query lenta às vezes?

É quando o SQL Server reutiliza um plano de execução otimizado para um valor de parâmetro específico, mas esse plano é ruim para outros valores. A query 'às vezes' fica rápida e 'às vezes' lenta com os mesmos dados, o que confunde o diagnóstico se você não souber procurar por isso.

Rebuild de índice resolve lentidão automaticamente?

Ajuda quando a causa é fragmentação, mas não resolve queries mal escritas ou ausência de índice adequado. Rode o rebuild como manutenção periódica, não como solução mágica para todo problema de performance.

BR
Editor de eventos, mapas e itens

Bruno é especialista em eventos, mapas, bosses e economia de itens do MU Online. Documenta cada detalhe com base em jogo real.

Continue lendo

Artigos relacionados