mirror of
https://github.com/esx-framework/esx_core.git
synced 2026-08-29 01:08:54 +00:00
perf(esx_multicharacter): look up characters by exact identifier instead of LIKE
The character selection query used `WHERE identifier LIKE 'char%:<license>'`. Every multicharacter identifier starts with `char`, so the primary key range covers the whole table and it degrades to a full scan on every join. Build the exact identifiers (`char1:<license>` .. `charN:<license>` for the player's slots) and query with `IN`, which hits the primary key directly. Measured on a 50k row users table (MariaDB 12.3.2): rows examined 45648 -> 3, query time 52.7 ms -> 3.2 ms. In-game the selection screen shows the same characters in the same slots.
This commit is contained in:
@@ -101,9 +101,17 @@ function Database:GetPlayerSlots(identifier)
|
||||
end
|
||||
|
||||
function Database:GetPlayerInfo(identifier, slots)
|
||||
local placeholders = {}
|
||||
local identifiers = {}
|
||||
|
||||
for i = 1, slots do
|
||||
placeholders[i] = "?"
|
||||
identifiers[i] = ("%s%s:%s"):format(Server.prefix, i, identifier)
|
||||
end
|
||||
|
||||
return MySQL.query.await(
|
||||
"SELECT identifier, accounts, job, job_grade, firstname, lastname, dateofbirth, sex, skin, disabled FROM users WHERE identifier LIKE ? LIMIT ?",
|
||||
{ identifier, slots })
|
||||
("SELECT identifier, accounts, job, job_grade, firstname, lastname, dateofbirth, sex, skin, disabled FROM users WHERE identifier IN (%s)"):format(table.concat(placeholders, ", ")),
|
||||
identifiers)
|
||||
end
|
||||
|
||||
function Database:SetSlots(identifier, slots)
|
||||
|
||||
@@ -14,7 +14,6 @@ function Multicharacter:SetupCharacters(source)
|
||||
ESX.Players[identifier] = source
|
||||
|
||||
local slots = Database:GetPlayerSlots(identifier)
|
||||
identifier = Server.prefix .. "%:" .. identifier
|
||||
|
||||
local rawCharacters = Database:GetPlayerInfo(identifier, slots)
|
||||
local characters
|
||||
|
||||
Reference in New Issue
Block a user