我有以下代码
h2.each {|k, v|
@count += 1
puts @count
sq.each do |word|
if Wordsdoc.find_by_docid(k).tf.include?(word)
sum += Wordsdoc.find_by_docid(k).tf[word] * @s[word]
end
end
rec_hash[k] = sum
sum = 0
}
h2->是一个包含文档ID的哈希,哈希包含1000多个
wordsdoc->是我的数据库中的模型/表…
sq->是一个包含大约10个单词的散列
我所做的是,我将通过每个文档ID,然后在SQ中的每个单词,如果单词存在,在单词DOC表中查找(WordsDoc .FiffyBythOdCid(k))。tf.include?(word),这里tf是{word=>value}的散列
如果是的话,我在Wordsdoc中得到这个单词的值,然后将它与@s中这个单词的值相乘,这个值也是{word=>value}
这看起来很慢Tt每秒处理一个文档有没有办法处理得更快?
非常感谢您的帮助!
最佳答案
你做了很多重复的查询。虽然activerecord可以在后台进行一些缓存以加快速度,但它所能做的事情是有限的,没有理由让事情变得更困难。
最明显的减速原因是Wordsdoc.find_by_docid(k)
。对于k
的每个值,您调用它10次,每次调用都有可能再次调用它。这意味着您对h2
中的每个条目使用相同的参数调用该方法10-20次对数据库的查询是昂贵的,因为数据库在硬盘上,在任何系统中访问硬盘都是昂贵的在进入Wordsdoc.find_by_Docid(k)
循环并将其存储在变量中之前,您可以同样轻松地调用sq.each
一次,这将节省大量查询,并使循环运行得更快。
另一个优化——虽然没有第一个那么重要——是在一个查询中获取所有wordsdoc记录。几乎都是中高级的(还有一些低级的!)编程语言和库在大量工作时工作得更好更快,activerecord也不例外。如果您可以查询Wordsdoc
的所有条目,并按docid
键中的h2
进行筛选,那么您可以(在第一次优化之后)打开1000个查询。在第一次优化之前,它是10000-20000个查询)到一个单一的、巨大的查询这将使activererocd和底层数据库能够以更大的块检索数据,并为您节省大量的磁盘访问。
你还可以做一些小的优化,但是我指定的这两个应该足够了。