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); LIMITquando 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.