我有以下代码

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和底层数据库能够以更大的块检索数据,并为您节省大量的磁盘访问。
你还可以做一些小的优化,但是我指定的这两个应该足够了。

09-26 06:51