Servidores de Jogos

Consultas com threads (mysql_tquery) e desempenho

Consultas com threads (mysql_tquery) e desempenho

O servidor open.mp processa a lógica do Pawn numa thread principal. Se uma consulta ao banco demora 200 ms e é síncrona, o servidor inteiro fica parado esses 200 ms, e todos os jogadores sentem o "lag".

Síncrono x assíncrono

  • mysql_query (síncrona): espera o resultado. Trava o servidor durante a consulta;
  • mysql_tquery (assíncrona): envia a consulta para outra thread e chama um callback quando o resultado chega. O servidor continua rodando.

Em produção, use mysql_tquery em praticamente tudo.

Exemplo com callback

stock CarregarConta(playerid)
{
    new query[128], nome[MAX_PLAYER_NAME];
    GetPlayerName(playerid, nome, sizeof(nome));
    mysql_format(Banco, query, sizeof(query),
        "SELECT id, senha_hash, dinheiro FROM contas WHERE nome = '%e' LIMIT 1", nome);
    mysql_tquery(Banco, query, "OnContaCarregada", "i", playerid);
}

forward OnContaCarregada(playerid);
public OnContaCarregada(playerid)
{
    if (cache_num_rows() == 0)
    {
        MostrarRegistro(playerid);
        return 1;
    }

    cache_get_value_name_int(0, "id", Jogador[playerid][jID]);
    cache_get_value_name_int(0, "dinheiro", Jogador[playerid][jDinheiro]);
    MostrarLogin(playerid);
    return 1;
}

Dentro do callback, as funções cache_* leem o resultado.

Cuidado: o jogador pode ter saído

Entre enviar a consulta e receber o resultado, o jogador pode ter desconectado, e outro pode ter entrado com o mesmo ID. Uma técnica comum é passar um identificador de sessão ou o race check:

new SessaoJogador[MAX_PLAYERS];

// ao conectar
SessaoJogador[playerid]++;

// ao consultar
mysql_tquery(Banco, query, "OnContaCarregada", "ii", playerid, SessaoJogador[playerid]);

// no callback
public OnContaCarregada(playerid, sessao)
{
    if (sessao != SessaoJogador[playerid]) return 1; // resultado antigo, ignora
    // ...
}

Mais desempenho no banco

  • Índices nas colunas usadas em WHERE (nome da conta, dono da casa);
  • LIMIT quando só precisa de uma linha;
  • Selecione só as colunas necessárias, não SELECT *;
  • Carregue dados estáticos (casas, empresas) uma vez no início, não a cada consulta;
  • Evite consultas dentro de loops. Prefira uma consulta que traga tudo.

Ordem das consultas

Consultas tquery na mesma conexão são executadas em ordem. Para consultas pesadas e independentes (relatórios, rankings), existe mysql_pquery, que usa várias conexões em paralelo e não garante ordem. Use com cuidado.

Hospede seu servidor com a VittHost

Os planos OPENMP-BR da VittHost incluem MySQL, com servidores no Brasil, painel Pterodactyl, proteção DDoS, compatibilidade total com scripts SA-MP e teste grátis de 3 dias.

Compartilhar:

Pronto para hospedar seu próximo projeto?

VPS com painel pré-instalado em 1 clique. Ativação imediata.

Ver planos VPS