Mysql High UPDATE SELECT вызывает задержку - PullRequest
0 голосов
/ 27 ноября 2011

У меня довольно внушительная игра, в которой максимум 30-40-50 человек играют в течение дня.Мы храним информацию об их танке в базе данных mysql, и когда они стреляют или теряют здоровье, мы сбрасываем ее в базу данных.Из-за этого мы видим очень высокий процессор и HDD Spike, и в результате получается отставание в игре.

Оскорбительные заявления:

UPDATE MapData
SET Health = @1, X = @2, Y = @3,TotalPoints = @4
   , RankPoints = @5
WHERE MapID = @6
   AND TankID = @7
   AND Color = @8

Я хочу знать, есть ли какие-то вещи, которые я могу сделать, чтобы помочь с отставанием вообще.

CREATE TABLE `mapdata` (
  `MapID` int(11) NOT NULL,
  `TankID` int(11) NOT NULL,
  `Color` tinyint(4) NOT NULL,
  `X` int(11) DEFAULT ''-1'',
  `Y` int(11) DEFAULT ''-1'',
  `Rank` tinyint(4) NOT NULL DEFAULT ''0'',
  `Health` int(11) NOT NULL DEFAULT ''1000'',
  `Armors` tinyint(4) NOT NULL DEFAULT ''0'',
  `Duals` tinyint(4) NOT NULL DEFAULT ''0'',
  `Missiles` tinyint(4) NOT NULL DEFAULT ''0'',
  `Homings` tinyint(4) NOT NULL DEFAULT ''0'',
  `Radars` tinyint(4) NOT NULL DEFAULT ''0'',
  `Beacons` tinyint(4) NOT NULL DEFAULT ''0'',
  `HasRankKill` bit(1) NOT NULL DEFAULT b''0'',
  `TotalPP` bigint(20) NOT NULL DEFAULT ''0'',
  `RankPP` bigint(20) NOT NULL DEFAULT ''0'',
  `KillCount` int(11) NOT NULL DEFAULT ''0'',
  `DeathCount` int(11) NOT NULL DEFAULT ''0'',
  `TimePlayed` time NOT NULL DEFAULT ''00:00:00'',
  `EnabledEquipment` tinyint(4) NOT NULL DEFAULT ''0'',
  `Prestige` tinyint(4) NOT NULL DEFAULT ''0'',
  PRIMARY KEY (`MapID`,`TankID`,`Color`),
  KEY `MapID` (`MapID`),
  KEY `TankID` (`TankID`),
  KEY `idx_mapdata` (`MapID`,`Color`,`TankID`),
  CONSTRAINT `mapdata_ibfk_1` FOREIGN KEY (`MapID`) REFERENCES `maps` (`ID`) ON DELETE CASCADE,
  CONSTRAINT `mapdata_ibfk_2` FOREIGN KEY (`TankID`) REFERENCES `tank` (`ID`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1

Можно ли как-нибудь сохранить таблицу в памяти, а не на жестком диске, и делать так, чтобы она часто возвращалась на диск?

Ответы [ 3 ]

2 голосов
/ 27 ноября 2011

Необходимо проверить, оптимизирована ли ваша конфигурация для InnoDB.Настройки MySQL по умолчанию обычно (в зависимости от конкретной версии, но все же) не оптимизированы для InnoDB, но больше подходят для движка MyISAM.

На сайте Percona есть хорошее введение в: Основы оптимизации производительности Innodb

Номер 5 в этом списке (настройка innodb_flush_log_at_trx_commit=2) - это именно то, что предложил Андреас.Есть еще много вариантов для изучения.


По вашему вопросу вы можете использовать Модуль памяти .Когда ваше приложение запускается, оно копирует таблицу с диска в идентичную таблицу памяти и использует ее впоследствии для всех операций, периодически обновляя таблицу дисков.Или он может загружать только те данные, которые ему нужны каждый раз (активен в данных игрока)


В качестве альтернативы вы можете добавить в приложение какой-либо механизм (задержки), который не отправляет каждое обновление как отдельную транзакцию, но


Еще одна вещь, которую вы можете рассмотреть, - вертикальное разбиение таблицы.Если у вас есть столбцы, которые обновляются редко, а некоторые - очень часто, вы можете разбить таблицу на две части.Затем обновления будут выполняться в таблицах с меньшей шириной.


У вас есть 4 индекса, но некоторые из них являются избыточными:

  PRIMARY KEY (`MapID`,`TankID`,`Color`),
  KEY `MapID` (`MapID`),
  KEY `TankID` (`TankID`),
  KEY `idx_mapdata` (`MapID`,`Color`,`TankID`),

KEY MapID (MapID) вообще не нужен, так как (1-я часть) Первичный ключ может использоваться вместо.

KEY idx_mapdata можно уменьшить до (MapID, Color)

2 голосов
/ 27 ноября 2011

Есть вещи, которые вы можете сделать, но вы достигли одного из трудных порогов для прохождения.Та, в которой у вас тяжелая система записи, и она просто не пишет достаточно быстро.

Есть несколько способов улучшить производительность

  1. Рассчитать значение бога для innodb_log_file_size
  2. Установить innodb_flush_log_at_trx_commit в 0 или 2. Обратите внимание, что 1 (по умолчанию) является единственным значением, совместимым с ACID, но изменение его на 0 или 2 дает гораздо лучшую производительность.

Конечно, есть и другие пути, но эти два важны.

1 голос
/ 27 ноября 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...