我有一台服务器,可以为连接到它的客户端写入数据库。与它的联系越多,写作就越多。我的问题是......我怎样才能最优雅地处理这个问题?随着数据库变得越来越大,插入/更新花费的时间越来越长,而后者随着服务器的响应越来越慢而滞后于客户端。
我想到的一件事就是拥有一个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'
答案 0 :(得分:0)
防止服务器陷入困境的典型方法是使用多线程。这允许服务器在线程处理数据库更新时继续响应传入的请求。我不确定mysql是否是线程安全的,因此您可能必须在数据库周围实现锁定。
答案 1 :(得分:0)
我为多人游戏做的这种方式是在线程上生成DBManager。
DBManager将是一个单例类,其中包含一个名为lock
的静态对象这有一个公共方法“Enqueue”可以将原始SQL或特定游戏对象保存到DB(在这种情况下为Tanks)
当您输入enqueue时,您在上面的锁定对象上调用Lock,并将其排入需要保存到DB的项目列表并返回,以便应用程序可以继续。
线程会每30秒左右唤醒一次,处理队列然后再回到睡眠状态。
此方法的缺点是您可能会丢失数据,因此您可能会失去睡眠/唤醒周期以降低风险,但显然会增加数据/处理器密集度。