Rails ActiveRecord查询:除非我将其拆分为2个查询,否则速度太慢。为什么?

时间:2013-09-14 06:55:51

标签: sql ruby-on-rails-3 activerecord

我的Post模型has_many :comments。它有一个搜索方法与此查询:

joins{comments.outer}.where{ (title.like_any search_words) | (body.like_any search_words) | (comments.body.like_any search_words) }

它提供了所需的记录:"查找标题,正文或其任何评论的所有帖子' body(如果有注释)匹配任何search_words"。 问题是: 这个查询需要8秒! 如果我把它分成2个查询,我可以让它在几毫秒内运行:

( where{ (title.like_any search_words) | (body.like_any search_words) }
 + joins{:comments}.where{ comments.body.like_any search_words } ).uniq

这给出了相同的结果,但速度要快得多。但是它会强制ActiveRecord::Relation成一个数组,所以我之后就无法执行.includes.pagination之类的操作。我真的希望将结果保持为ActiveRecord::Relation,但我希望它更快。你会做什么?

PS:我在这里使用Squeel。

感谢。

2 个答案:

答案 0 :(得分:1)

如果您使用的是rails 4,则可以进行查询链接。否则你可以做的就是选择你需要显示的必填字段。并且还要对搜索字段进行正确的索引,但要确保在添加索引之前和之后请检查您的性能。 或另一个选项是编写一个必需的SQL查询。并通过rails中的find_by_sql方法使用它。

答案 1 :(得分:0)

两个单独的查询imho将会明显更快,因为它们更简单,更容易进行数据库优化。

理想情况下,人们想要的是这两个查询的union。不幸的是,afaik,ActiveRecord / Arel / Squeel中不存在此功能。所以你必须编写自己的查询来解决这个问题。

当然:我不确定如果你执行两个查询,union,然后是distinct,你将无法获得与第一个查询相同的执行速度。

我通常使用postgresql(会推荐),但我注意到MySQL也支持FULLTEXT indexes,所以你可能想看一下。