你使用的
scan
创建了一个数组,计算其大小,然后将其丢弃。如果在大文件中有许多子字符串的出现,您将暂时创建一个大数组,可能会因内存管理而消耗CPU时间,但即使是300MB,它仍应该运行得非常快。
由于Word是一个ActiveRecord类,它依赖于数据库中的架构和任何索引,以及您的数据库服务器可能遇到的任何问题。如果数据库未经过优化或响应缓慢,或用于检索数据的查询不高效,则迭代将变慢。您可能会发现,抓取
Word
组以使它们位于RAM中,然后对它们进行迭代会更快。
如果数据库和您的代码在同一台机器上运行,那么您可能会遭受资源限制,例如只有一个驱动器,内存不足等。
没有更多关于您的环境和硬件的信息,很难说。
编辑:
我可以先将子字符串抓取到数组/哈希表中,然后将计数结果添加到数组或哈希表中,在完成所有计数后将结果写回数据库。你认为这会更快,对吗?
不,我怀疑这样做并不能帮助很多,而且如果不知道问题出在哪里,你可能只会让问题变得更糟,因为你需要从数据库中加载10,000条记录作为对象,然后构建一个有10,000个元素的哈希表或数组,它们也将与DB记录一起存储在内存中,然后再将它们写出。
Ruby目前只使用单个核心,但您可以通过使用Ruby 1.9+来提高速度。我建议安装RVM并让它管理您的Ruby。请确保阅读该页面上的说明,然后运行rvm notes
并遵循那些指示。
您的Word模型和底层架构以及索引是什么样子?数据库是否在同一台机器上?
编辑:根据您的表模式,除了id
之外,您没有索引,这对于普通查找帮助不大。我建议在Stack Overflow的姊妹站点https://dba.stackexchange.com/上展示您的模式,并解释您想要做什么。至少我会添加一个键到文本字段以帮助避免任何搜索时进行完整表扫描。
更有帮助的是阅读来自“Active Record Query Interface”Retrieving Multiple Objects in Batches的内容。
此外,请查看运行Word.each
时发出的SQL。它是否类似于"select * from word"
?如果是,那么Rails将读取10,000条记录以逐个迭代它们。如果是类似于"select * from word where id=1"
,则对于每个记录,在更新计数时都会进行数据库读取后跟写入。这就是“以批处理方式检索多个对象”链接将有助于修复的情况。
此外,我猜测
content
是您正在搜索的文本,但我不能确定。您是否有重复的文本值,导致您多次扫描相同的文本?如果是这样,请使用该字段上的
unique
条件选择记录,然后一次性更新所有匹配记录的计数。
您是否对您的代码进行了剖析,以查看Ruby本身是否可以帮助您找出问题所在?将您的代码修改一下,以处理100或1000条记录。使用
-r profile
标志启动应用程序。当应用程序退出时,分析器将输出一个表格,显示时间花费在哪里。
您运行哪个版本的Rails?