C# 服务器端数据库写入的最佳策略

C# 服务器端数据库写入的最佳策略,c#,mysql,C#,Mysql,我有一个服务器,它可以为连接到数据库的客户端对数据库进行多次写入。与它的联系越多,它的写作就越多。我的问题是。。我怎样才能最优雅地处理这件事?随着数据库变得越来越大,插入/更新所花费的时间越来越长,这反过来又使客户端滞后,因为服务器的响应速度越来越慢 我考虑过的一件事是有一个DB Helper程序,我将它写入队列数据库,作为一个单独的应用程序,它将在分配时写入。这将使服务器更加专注,但我不确定这是否是最好的途径 任何帮助都会很好 <Debug> -- 10/6/2012 8:57:1

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

我考虑过的一件事是有一个DB Helper程序,我将它写入队列数据库,作为一个单独的应用程序,它将在分配时写入。这将使服务器更加专注,但我不确定这是否是最好的途径

任何帮助都会很好

<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

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

我在多人游戏中这样做的方式是在线程上生成一个DBManager

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

它有一个单一的公共方法“Enqueue”,将原始SQL或特定的游戏对象保存到DB(本例中为Tanks)

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

线程将每隔30秒左右醒来,处理队列,然后返回睡眠状态


这种方法的缺点是,您可能会丢失数据,因此您可能会失去睡眠/唤醒周期以降低风险,但显然,这需要更多的数据/处理器密集度。

我只想澄清一下,这只是写入,而不是读取?你有什么不需要的索引吗?我已经更新了记录单,添加了一些问题孩子的日志。从2012年起你还在做这个吗?渐进式的减速可能来自插入表中的许多索引。把大部分都去掉。迁移到MS SQL或其他RDBMS也很好。不,哈哈,这真的很老了,我只是提供了最终对我有用的东西。我不知道为什么人们对我自己的答案投反对票。有人想说,投反对票的解决方案不好。
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'