我的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。
感谢。
答案 0 :(得分:1)
如果您使用的是rails 4,则可以进行查询链接。否则你可以做的就是选择你需要显示的必填字段。并且还要对搜索字段进行正确的索引,但要确保在添加索引之前和之后请检查您的性能。
或另一个选项是编写一个必需的SQL查询。并通过rails中的find_by_sql
方法使用它。
答案 1 :(得分:0)
两个单独的查询imho将会明显更快,因为它们更简单,更容易进行数据库优化。
理想情况下,人们想要的是这两个查询的union
。不幸的是,afaik,ActiveRecord / Arel / Squeel中不存在此功能。所以你必须编写自己的查询来解决这个问题。
当然:我不确定如果你执行两个查询,union,然后是distinct,你将无法获得与第一个查询相同的执行速度。
我通常使用postgresql(会推荐),但我注意到MySQL也支持FULLTEXT
indexes,所以你可能想看一下。