Здравствуйте, не знаю как правильно сформулировать заголовок запроса. Постараюсь отразить в деталях.
Есть некая абстрактная БД на mysql, в которых я по сути заполняю лишь одну колонку - result.
Где id = Auto Increment , остальные колонки заполняются инсертами.
Есть некоторое устройство (на самом деле таких устройств может быть десятки), которое может генерировать данные с периодичностью 0.001сек. Периодичность меняется, но я закладываю максимальную скорость генерации.
C устройства передаются данные, которые заполняются в колонки (sessid и result)
Само устройство пишет не напрямую в базу, а передаёт данные в обработчик, на котором я реализовал следующую логику -
->Поступают данные с устройства ->
->выполняется проверка наличия sessid в базе
SELECT
table.serialnumb
FROM
table
WHERE
sessid = $sess.id$
ORDER BY
base.table DESC
LIMIT 1
Таким образом я получаю наибольшее значение serialnumb для данного sessid->
->если не найдено выполняется -
INSERT INTO `base`.`table`(`sessid`, `serialnumb`, `result`, `numnum`) VALUES ('$sess.id', 0, '0', $numnum)
и отправляется заново на проверку наличия sessid в базе->
->Если найдено - выполняю проверку уникальность result в данном sessid (не должно быть двух одинаковых result для одного sessid). Повторные значения result отбрасываю. ->
->Уникальное значение - беру serialnumb +1 и делаю инсерт
INSERT INTO `base`.`table`(`sessid`, `serialnumb`, `result`, `numnum`) VALUES ('$sess.id$', $sess.newlastnum$, '$rand$', $numnum$)
Собственно, я продебажил на разном железе, но в рамках ВМ (на вм стоит mysql и на отдельной вм стоит обработчик на node) у меня получилось так
Intel Platinum 8380 + ddr4
Самый толстый запрос усреднённо 0.04 сек занимает (select с 100 тыс.строк данных)
Ryzen 7 7800x3D + ddr5
тот же запрос 0.035 сек
Тестовый стенд intel xeon gold 6130
тот же запрос усредненно 0.1 сек
Проблема в том, что serialnumb должен быть уникальный в рамках sessid. Чего не получается добиться при большой интенсивности запросов.
Причина-следственная связь ясна, из за большого наплыва информации select отрабатывает раньше у части запросов, в связи с чем отдается устаревший serialnumb, в связи с чем один serialnumb прописывается для нескольких запросов.
В итоговом решение - железо будет использовать энергоэффективное, соответственно вариант с железом отметаем.
Можно оптимизировать запросы + оптимизировать саму БД (т.к. она она стоковая без тюнинга mariadb 10.5) - но не думаю что приведет к исключению проблемы.
Как решение, вижу такой способ. Добавление всех записей во временную таблицу, Где будет 3 колонки (id (auto incremet), sessid, result) и далее уже перенос в актуальную таблицу. Но это может дать лаг при анализе данных на frontend, чего хотелось бы избежать. По этой же причине не хотелось бы делать задержку ожидания на обработчике, (тогда там memory может вспухнуть если будет гигантская очередь).
Подскажите, какие способы оптимизации или решения моего вопроса воспользовались бы Вы? Может я где-то нарушил логическую цепочку ?