1

我有一台服务器,它为连接到它的客户端对数据库进行多次写入。与它的联系越多,它的写作就越多。我的问题是..我怎样才能最优雅地处理这个?随着数据库变得越来越大,插入/更新花费的时间越来越长,这反过来又落后于客户端,因为来自服务器的响应越来越慢。

我想到的一件事是拥有一个 DB Helper 程序,我将其写入 QUEUE 数据库,并作为一个单独的应用程序,它将在分配时写入。这将使服务器更加专注,但我不确定这是否是最佳路线。

任何帮助都会很棒。

<Debug> -- 10/6/2012 8:57:15 PM -- UPDATE mapdata SET X = @1, Y = @2, Rank = @3, Health = @4, Beacons = @20,Armors = @5, Duals = @6, Missiles = @7, Homings = @8, Radars = @9, HasRankKill = @10, TotalPP = @11, RankPP = @12, KillCount = @13, DeathCount = @14, TimePlayed = @15, EnabledEquipment = @16 WHERE MapID = @17 AND TankID = @18 AND Color = @19;
<Debug> -- 10/6/2012 8:57:15 PM -- Time to execute: 00:00:00.0468003

这需要半秒钟才能执行。

我在 MapData 上有如下索引:

PRIMARY: MapID, TankID, Color
MapID: MapID
TankID: TankID

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

2 回答 2

0

防止服务器陷入困境的典型方法是使用多线程。这允许服务器在线程处理数据库更新时继续响应传入的请求。我不确定 mysql 是否是线程安全的,因此您可能必须在数据库周围实现锁定。

于 2012-10-07T00:55:28.437 回答
0

我为多人游戏所做的方法是在线程上生成一个 DBManager。

DBManager 将是一个单例类,带有一个名为 lock 的静态对象

这有一个公共方法“Enqueue”,它将采用原始 SQL 或特定游戏对象保存到数据库(在这种情况下为坦克)

当您进入 enqueue 时,您在上面的锁定对象上调用 Lock,并将需要保存到 DB 的项目列表排入队列并返回,以便应用程序可以继续。

The thread would wake up every 30 seconds or so, process the queue and then go back to sleep.

The down side to this method is that you will have a potential for data loss, so you can lose the sleep/wake cycle to reduce the risk but obviously thats a bit more data/processor intensive.

于 2017-05-01T20:44:12.970 回答