我在mysql中有一个这样的表
CREATE TABLE IF NOT EXISTS `connections` (
`src` int(10) unsigned NOT NULL,
`sport` smallint(5) unsigned NOT NULL,
`dst` int(10) unsigned NOT NULL,
`dport` smallint(5) unsigned NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`src`,`sport`,`dst`,`dport`,`time`),
KEY `time` (`time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
每天有 250 万条记录插入此表。
当我想选择某段时间(比如一天)的记录时。大约需要 7 分钟。 我该如何改进它。
我正在使用 ruby on rails 版本 4.0.0
我的选择是这样的
connections = Connection.select('src, dst, UNIX_TIMESTAMP(time) as time')
.where(time: timeFrom..timeTo)
.order('time ASC')
从数据库中选择后,我有一个这样的循环:
connections.each do |con|
link = getServerID(con['src'])
link = getServerID(con['dst']) if link == 0
@total[link].append [con['time'] * 1000, con['dst']]
end
在这个循环中,我对 src 和 dst 进行了一些处理,然后将其添加到哈希中 这部分发生了,我的电脑死机了
最佳答案
首先,您应该尝试在没有 Rails 的情况下直接对数据库运行 SQL 查询。这有助于确定瓶颈:是查询本身慢还是 rails 慢?我想 SQL 部分应该不是问题,但请先仔细检查一下。
我猜你最大的问题在于connections.each
。这会将所有匹配的行加载到您的应用程序中,并为其创建 ActiveRecord
模型。让我们做一些计算:2.5M 条目 * 1KB
(只是猜测,可能更多)将导致 2.5GB
的数据加载到您的内存中。您可能会看到使用 connection.find_each
的改进,因为它以较小的批处理加载连接。
getServerID
方法有什么作用?它被调用了 5M
次。
我很确定您无法对这段代码进行太多改进。似乎是问题的错误数据库或错误的算法。由于您不太可能希望在网站上显示 2.5M
记录,因此最好告诉我们您想要实现的目标。
关于mysql - 如何使用 mysql 每天处理数百万条记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19241332/