我有一个在线游戏,我记录了很多游戏玩法统计数据。这些统计表变得非常快,我必须要小心,因为只要记录更多的统计数据,一旦表格变得足够大,就会导致游戏的性能变差。
我的策略,不是一个非常好的策略,是保持统计表小。我有一个自动过程,每24小时创建一个新表,防止性能过于失控。但我的解决方案很难看,是统计表的一种“轮换”。我使用innodb并设置了几个索引以提高性能,然后我只保留了30个这些表(每个都是24小时,所以我节省了一个月的统计数据)。每24小时,我的自动进程会删除“stats30”表,然后将所有编号的表重命名为更高的数字,然后创建一个名为“stats”的新空白表。这是“实时”表格,其中统计数据被积极记录。
这些表基本上记录了每个玩家与他们互动的游戏中每个其他玩家之间的每笔交易,从而导致数据呈指数级增长。当一个新的交易发生时,它会检查当天这两个玩家之间的交易是否已经有一行。如果有,它会更新行以更改其事务。否则,它会创建一个新行。一对玩家每天互动1000次,一对互动一次只会在当天的桌子上只有一行。数据库上的每个操作都涉及一个SELECT,然后是UPDATE或INSERT,因此它在读取和写入之间甚至是当前设计的。相对于单个SELECT,UPDATE和INSERT,更广泛意义上的数据读取,即用于分析统计数据和多个玩家,很少进行。每天创建大约150,000行。
我知道这可能会更好。我不能轻易减少我录制的数据量,但我关注的是1.performance和2.simplicity。例如,我可以通过每4小时创建一个新表来提高性能,但是我必须弄乱180个表。相反,我可以通过使用一个表来简化它,然后一切都嘎然而止。
请注意,我确实需要更新这些表中的行,所以我不能使用类似ARCHIVE存储引擎的东西,但我只需要在“实时”统计表上插入或更新。
还有一个小问题,即当每日轮换过程发生时,当时进入的任何查询都可能丢失。 (如果它正在重命名所有表并创建一个新表,新条目可能会失败。)丢失一些插入不是一个大问题,而是一个不会发生此错误的解决方案,或者可以“原子地”完成“会更好。
感谢任何可能有帮助的想法! :)
答案 0 :(得分:2)
每天有150k行,平均值是多少。一排的大小? 这些行是否包含您可以通过仅保留引用来最小化的冗余数据?
通常,保持表小,以便索引更新快速完成总是一件好事。此外,如上面提到的Ben S,您的查询应至少进行优化,以便无法访问缺少索引的列等。如果您使用EXPLAIN和mysql服务器的慢查询日志,可以找到一些可能的问题启用它。
可能有助于解决性能问题的一件事是memcached守护程序。使用它你可以延迟写入你的数据库,从而取出一些蒸汽,仍然不会受到脏缓存和类似的困扰。虽然取决于您正在使用的应用程序框架(如果有的话),但需要一些工作才能将其实现到您的应用程序中。
为了存档和统计目的,我建议你看一下InfoBright(http://www.infobright.org/)。这是一个开源的MySQL代替(基于MySQL)。它的目的是成为一个数据仓库商店。您可以将它用于各种高容量数据分析。 它有一个非常好的压缩功能,在我们的例子中,将大约23TB的原始数据减少到大约1.2TB的压缩数据。我想不用说查询特定的压缩数据行可能会非常慢。但对于统计数据来说,它的速度非常快。因此,如果您没有查询特定的行,而是分析诸如“在08年12月到09日之间使用值foo>条更新了多少行”这样的内容,它将为您提供非常好的性能。事实上,当您使用数据库时,它将分析您的使用情况并创建一个知识网格,以优化您的特定查询的数据。
我想到的下一个问题是......如果你只保留一天或几个小时的“仅”统计数据/会话数据,那么关系数据库是适合这项工作的工具吗? 在不知道应用程序的确切性质的情况下,我可以想象某种内存中的会话(例如可以驻留在兵马俑集群中),它们编写事务日志并且每隔一段时间提交它们的数据可能更适合。但正如我所说,这在很大程度上取决于您的应用程序的性质和相关数据的大量数据。
答案 1 :(得分:0)
没有数据库大师,但您尝试过使用不同的数据库引擎(innoDB很慢,请尝试myISAM)并确保您选择的数据已编入索引吗?
似乎是一个愚蠢的问题但是,你拥有的解决方案非常疯狂
还可以尝试:http://forums.mysql.com/read.php?24,92131,92131进行性能调整。
答案 2 :(得分:0)
要做的第一件事是分析您的应用程序以找到实际花费最多时间的内容。如果另一个更改可以提供更好的性能,则无法继续使用此表旋转。
对您的所有问题运行EXPLAIN,并确保您了解结果并optimize your queries appropriately。
我还强烈建议您阅读Reference Manual for optimizing MySQL。它提供了许多有关如何配置服务器以获得最佳性能的提示,并可能让您深入了解可能导致性能瓶颈的原因。
如果实时表的性能确实是问题,您需要减少该表中的行数,那么只需将行移动到存档表即可。这样你总是有一个苗条的现场表。并且可以轻松地在存档上运行更长时间运行的查询。
答案 3 :(得分:0)
我们在这里谈论了多少行?百万?成千上万?
因为你说你只需要更新实时表中的行,听起来你可能只用两个表 - 一个实时统计表和一个统计表。然后,您的批处理作业将定期将行从统计信息表中的行移动到stats_archive表。另一项工作可能会在达到某个年龄后从存档表中清除行。最好有一个第三个工作,定期重新计算存档表中的统计信息,以确保MySQL可以为您的查询生成良好的计划。
答案 4 :(得分:0)
我想更多地了解您的域名,以提供更准确的答案。但简短的回答是,您需要基于月,年或基于地理位置的某种分区。因此,属于特定城市的所有用户统计信息都将进入这些表格。通过这种方式,您的选择可以变得更快。
当然,通常关于添加索引的yada yada ...
告诉我更多信息,我或许可以帮助你...