【发布时间】:2015-04-18 12:33:12
【问题描述】:
我有一堆将数据发送到 mysql 服务器的移动应用程序。每个应用程序都有自己的表,它可以在短短几周内轻松达到 100,000 多条记录。我目前每天大约有 1000 万次调用数据库。我的系统当前设置的方式是每 5 分钟一个 cron 将为每个表运行一堆查询并将 html 缓存到一个文件中。然后,当用户调用排行榜时,我运行 1 个查询来获取他们当前的排名,然后我显示缓存的 html 以及我从查询中提取的排名。
虽然这可行,但我希望更改它有两个主要原因。我想在客户端而不是在我的服务器上提供排行榜。我想发送 json 然后在他们的设备上解析它。我还想为每个应用添加每日、每周、每月和所有时间的排行榜。目前我存储数据的方式不允许这样做。
我的问题是
将 json 发送给用户的最佳方式是什么?像我在文件中处理 html 一样缓存 json 然后让用户调用该文件是否明智?对此唯一的抱怨是我需要为每个应用程序(每天、每周、每月、所有时间)创建 4 个 json 文件。
如果想要添加每日、每周、每月和所有时间的分数,数据库结构会是什么样子?我已经为我的一些应用程序添加了每日分数,但我停止了这样做,因为这似乎是一种糟糕的做法。我基本上保留了所有用户的大列表以及他们开始一天的工作,每次他们更新他们的分数时,我都会将其与他们存储的分数进行比较并得到差异。该表对于每日而言很快就变得非常大,如果我每周和每月都有数百万条记录,那将很容易。
我每个应用的表结构真的很简单
CREATE TABLE `app_test1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`deviceID` varchar(50) NOT NULL,
`username` varchar(25) NOT NULL,
`score` int(11) unsigned NOT NULL
PRIMARY KEY (`id`),
UNIQUE KEY `deviceID_2` (`deviceID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
通常我会进行更改并在我认为合适的情况下对其进行调整,但是有这么多调用我发现很多次一个简单的小更改很容易使服务器崩溃所以现在我喜欢在我之前获得想法甚至尝试任何事情。
【问题讨论】:
-
另外我想知道将用户排名存储在数据库中然后运行 cron 每隔几分钟更新一次排名是否明智?
-
为了限制所涉及的数据量,我建议对表进行规范化,以便将 deviceID 和用户名存储在其他地方,而不是使用 varchar(50) 和 varchar(25) 你有 2 (较小的)整数。想一想,您可能可以将用户名和设备合并到一个外部表中;这样,您就可以从 varchar(75) 转到单个 int,从而严重减少使用的表空间和索引空间。因此更少的 I/O 和改进的缓存(更多的数据适合相同数量的 ram)。
-
在我们运行和过早优化之前——您每秒有多少查询? 5 分钟 cron 作业中的查询需要多长时间?分数有变化吗?那就是用户设备到昨天的总点数会保持不变吗?而你只需要在重新计算排名之前添加今天的积分?
-
@deroby 我如何将 deviceID 保存在不同的表中,它是该表中的唯一键。将用户名存储在不同的表中是否有意义?现在我每个应用程序都有一个表,因为我发现它运行得更快,因为表更小。如果我将所有用户名存储在他们自己的表中,那么该表很容易增长到数百万。这样做会更好吗,并且必须查询具有数百万条记录的表?
-
哎呀,你确实在
deviceID上放了一个UQ,对不起,没注意到。这让我关于标准化的观点变得毫无意义,对此感到抱歉。再说一次,仔细看看我不确定我是否完全理解CREATE TABLE的语法,KEY 'score' ('score', 'appname')是做什么的? (看起来appname还不是表格的一部分(还)?你在桌子上得到了很多插入,DeviceID可能会陆续出现吗?如果是这样,我会摆脱@987654327 @autonumber 并使用deviceID作为PK。但是如果它随机进入会导致碎片=(
标签: mysql query-optimization leaderboard