> > > >

[SQL] Скорость выполнения запросов

Сообщения
330
Рейтинг
360
#1
Хочется ради интереса поинтересоваться, приемлема ли такая скорость выполнения запросов?
Статистика игроков на SQLite, обновление данных идет по таймеру раз в 60 секунд.
Итого имеем.
2019-03-13_191914.png

Смутило то, что почему время идет по увеличению прям, и теперь задумываюсь, последняя скорость это скорость выполнения последнего запроса или в общем всех?
Ибо если смотреть по времени создания строки с логами, то буквально за секунду произошел апдейт.

Код:
public DataUpdateTask() {
    new aPlayersID[MAX_PLAYERS], iPlayersNum, iSysTime = get_systime();
    get_players_ex(aPlayersID, iPlayersNum, GetPlayers_ExcludeBots | GetPlayers_ExcludeHLTV);
    
    for(new i; i < iPlayersNum; i++) {
        if(iSysTime - g_aLastDataUpdate[aPlayersID[i]] >= DATA_UPDATE_TIMER) {
            DataUpdate(aPlayersID[i]);
            g_aLastDataUpdate[aPlayersID[i]] = iSysTime;
        }
    }
}


DataUpdate(id) {
    new sQuoteStringPlayerName[PLAYER_NAME_STRLEN * 2];
    SQL_QuoteString(Empty_Handle, sQuoteStringPlayerName, charsmax(sQuoteStringPlayerName), g_eData[id][pd_sName]);
    
    formatex(g_sSQLQuery, charsmax(g_sSQLQuery),
        "UPDATE players_stats SET \
        Name = '%s', \
        Kills = %d, \
        Deaths = %d, \
        Head = %d, \
        Skill = %f, \
        LastSeen = %d \
        WHERE AuthID = '%s'",
        sQuoteStringPlayerName,
        g_eData[id][pd_iKills],
        g_eData[id][pd_iDeaths],
        g_eData[id][pd_iHead],
        g_eData[id][pd_fSkill],
        g_eData[id][pd_iLastSeen],
        g_eData[id][pd_sAuthID]
    );
    
    SQL_ThreadQuery(g_hSQLTuple, "DataUpdateQueryHandler", g_sSQLQuery);
}


public DataUpdateQueryHandler(iFailState, Handle:hQuery, sError[], iErrNum, aData[], iSize, Float:fQueueTime) {
    Logging(g_sLogsDir, "stats_inform_", "^"[DataUpdateQueryHandler] Queue Time %f^"", fQueueTime); //%.2f
    
    if(iFailState != TQUERY_SUCCESS) {
        SQL_GetQueryString(hQuery, g_sSQLQuery, charsmax(g_sSQLQuery));
        QueryHandlerError(g_sSQLQuery, sError, "DataUpdateQueryHandler");
        return PLUGIN_CONTINUE;
    }
    return PLUGIN_CONTINUE;
}
 
 
Сообщения
264
Рейтинг
211
#2
Если я правильно понимаю, то запросы выполняются хоть и в одном потоке, но всего в одном. Пока первый запрос выполняется остальные ставятся в очередь, вот с увеличением очереди и время растет.
13 Мар 2019
Смотри что будет через 60 секунд, когда пойдет следующая пачка запросов
 
 
Сообщения
330
Рейтинг
360
#3
Смотри что будет через 60 секунд, когда пойдет следующая пачка запросов
Что смотреть то? Все то же самое, отправляется новая пачка запросов и так циклично.

В 20:07
2019-03-13_201041.png

В 20:08
2019-03-13_201123.png

Если бы каждый запрос выполнялся действительно за ~0.5 секунд, то в целом пачка бы отправилась за ~10 секунд.
Скорее всего так и получается, что ждет своей очереди, итого все запросы выполнились за 0.8 секунд.
 
 
Сообщения
100
Рейтинг
77
#4
 
Сообщения
256
Рейтинг
290
#5
Стату можно в реал-тайме обновлять, а запросы обрабатывать на стороннем сервере (mysql), что дает увлечение скорости получения ответа и разгрузку основного сервера.
13 Мар 2019
А долго обрабатывается скорее всего из-за обновления 32 раза по AuthID. Попробуй при коннекте сохранять id игрока из бд и через него обновлять, потому что сравнение строк AuthID дорогое удовольствие.
 
 
Сообщения
330
Рейтинг
360
#8
Всех запросов вместе.

0.05*
Если сложить в сумме скорость всех запросов и разделить на их общее количество, то получится ~0.5
13 Мар 2019
fl0wer, 1. Ну, получать id при коннекте я опять таки буду по AuthID, иначе как я его получу еще? 2. Если игрока нету в базе, как я ему присвою id(при добавлении нового игрока) который мне неизвестен будет или я сейчас не понимаю что-то?
 
 
Сообщения
256
Рейтинг
290
#9
Javekson, одно дело только при коннекте, не так затратно. Если нет, то добавляешь и получаешь добавленный ид, если есть, то просто берешь.
13 Мар 2019
fl0wer, ты имеешь ввиду добавить поле id как AUTO_INCREMENT ?
ещё и индекс повесить на authid и на id
 
 
Сообщения
330
Рейтинг
360
#12
fl0wer, По-моему в SQLite этот индекс не работает, ибо ошибку выдало о неверном синтаксисе.
14 Мар 2019
Кажется все же придется на MySQL переходить, дурная затея делать SQLite
 
 
Сообщения
291
Рейтинг
586
#13
fl0wer, По-моему в SQLite этот индекс не работает
Работает (во всяком случае, создавать можно). Пример ниже создаст уникальный индекс (если я правильно понимаю, что это индекс) для authid (т.е. подразумевается, что каждый конкретный `authid` может быть только в одной записи / таблица), что по идее тебе и нужно. Чтобы понять, какой выигрыш в скорости это даёт (и даёт ли), нужно создать 2 идентичные таблицы, с индексом и без, наполнить их идентичной инфой (хотя бы 5к записей), и затем производить тестовые выборки по authid (т.е. "... WHERE `authid` = ..."), сравнивая скорость выполенения.

Код:
CREATE TABLE IF NOT EXISTS `test_table` (
  `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
  `authid` TEXT NOT NULL UNIQUE,
  `kills` INTEGER NOT NULL,
  `deaths` INTEGER NOT NULL,
  `last_seen` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
 
 
Сообщения
330
Рейтинг
360
#14
BlackSignature, проверил с индексом и без, выигрыша в скорости нету, 32 запроса выполняются так же ~1 сек.
Правда с ID полем не проверял, не создавал его еще пока что.
 
 
Сообщения
291
Рейтинг
586
#15
Код:
CREATE TABLE `test_table` (
					`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
					`authid` TEXT NOT NULL,
					`kills` INTEGER NOT NULL,
					`deaths` INTEGER NOT NULL,
					`last_seen` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE UNIQUE INDEX "authid"
ON "test_table" ("authid" ASC);
Есть ещё такой вариант (редактор выдал). Возможно в 1-ом варианте совсем и не индекс получается, а просто устанавливается требование к уникальности столбца `authid`
 
 
Сообщения
496
Рейтинг
584
#16
BlackSignature,
Код:
CREATE TABLE `test_table` (
                    `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
                    `authid` TEXT NOT NULL,
                    `kills` INTEGER NOT NULL,
                    `deaths` INTEGER NOT NULL,
                    `last_seen` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE UNIQUE INDEX "authid"
ON "test_table" ("authid" ASC);
Есть ещё такой вариант (редактор выдал). Возможно в 1-ом варианте совсем и не индекс получается, а просто устанавливается требование к уникальности столбца `authid`
Это так, индекс надо создавать отдельно.
Насчёт CREATE UNIQUE INDEX "authid" не уверен, authid уникально ли? Может, просто CREATE INDEX "authid" ?
 
 
Сообщения
74
Рейтинг
181
#17
32 запроса выполняются так же ~1 сек.
Чтобы понять, какой выигрыш в скорости это даёт (и даёт ли), нужно создать 2 идентичные таблицы, с индексом и без, наполнить их идентичной инфой (хотя бы 5к записей)
Индексы дают прирост на выборку с условиями (WHERE), но небольшую потерю на запись, в любом случае.
 
 
Сообщения
330
Рейтинг
360
#18
Индексы дают прирост на выборку с условиями (WHERE), но небольшую потерю на запись, в любом случае.
именно на запись? или update тоже?
15 Мар 2019
Поговорил с BlackSignature и понял, что поиск по поле AuthID с индексом будет осуществляться гораздо быстрее.
Мне кажется статья которую я читал немного недоработанная полнотой информации по этому поводу.

Без индексов поиск осуществляется как:
EXPLAIN QUERY PLAN SELECT * FROM players_stats WHERE AuthID = 'STEAM_1:0:357741490'
SCAN TABLE players_stats
Что является самым глупым поиском по таблице, перебирая и сравнения все значения в базе.

А вот по индексу:
EXPLAIN QUERY PLAN SELECT * FROM players_stats WHERE AuthID = 'STEAM_1:0:357741490'
SEARCH TABLE players_stats USING INDEX indexID (AuthID=?)

Поиск осуществился по индексу, что гораздо быстрее и эффективнее особенно при объемных базах.

Так же BlackSignature приложил видео для визуального понимания.

 
 
Сообщения
1.433
Рейтинг
1489
#19
Javekson, Так об этих индексах я говорил еще в чате. Не надо добавлять никакие ID, автоинкременты. Достаточно установить индекс. Но все же есть еще одно поле skill по которому идет поиск. Стоит также расмотреть возможность раставить индекс там. И поздравляю. Ты один из немногих, кто пользуется EXPLAIN
 
 
Сообщения
330
Рейтинг
360
#20
Так об этих индексах я говорил еще в чате.
Я знаю, но тогда я не понимал этого, пока визуально не понял как это работает.

Не надо добавлять никакие ID, автоинкременты
я тоже об этом задумался, что поле id будет не нужен в принципе, если есть индекс на SID'e

И поздравляю. Ты один из немногих, кто пользуется EXPLAIN
BlackSignature подсказал, я даже не знал об этом, лишь только потом посмотрел пару видео по этому поводу.
 
 

Пользователи, читающие эту тему

Сейчас на форуме нет ни одного пользователя.
> > > >