【问题标题】:How do I optimize a select query in Activerecord?如何优化 Activerecord 中的选择查询?
【发布时间】:2015-05-23 16:20:33
【问题描述】:

我正在寻找是否有更好的方法来编写以下 ActiveRecord 查询。

@posts = Post.select {|x| x.section.nil?} 

我对这个查询所做的是搜索帖子,然后只选择不再关联部分且处于孤立状态的帖子。

有没有更好的方法来做到这一点?我正在使用 Rails 3.2。

非常感谢。

【问题讨论】:

  • Post.where(:section_id => nil)
  • 是的,这是行不通的,因为 :section_id 并不是真的为零。它实际上有一个孤立的部分 id。在上面的代码中,它通过检查该部分的 id 并返回包含不存在的部分的帖子来检查该部分是否存在。
  • 试试这个Post.includes(:section).where(:section => { :id => nil })
  • @Sontya,由于您使用的是包含(用于急切加载),因此您还必须添加对该表的引用才能对该包含的表进行查询。
  • 是的。因此,如果 OP 在 Post 模型 has_many :section, :class_name => 'Post', :foreign_key => 'post_id' 中有类似的东西,那么 Post.includes(:section).where(section_posts: { id: nil }) 它应该可以工作

标签: ruby-on-rails ruby activerecord ruby-on-rails-3.2


【解决方案1】:

这应该可行:

Post.joins('left outer join sections on sections.id = posts.section_id').where('sections.id is null and posts.section_id is not null')

或更短的方式,使用eager_load:

Post.eager_load(:section).where('sections.id is null and posts.section_id is not null')

【讨论】:

  • 太棒了!第一个选项就像一个魅力!感谢您的帮助。
  • @MikeR 第二个也应该完成它的工作 - 并且看起来更好,因为您不必自己构建 join 子句。
  • 由于某种原因,第二个选项不起作用。这就是我得到的:#<:friendlyidactiverecordrelation:0x3febacd11834> 我将继续使用第一个。再次感谢您的帮助。
  • @MarekLipka,为什么我需要明确告诉左外连接,其中包含/eager_load 对我来说是这样的?
  • @MikeR 它在这里不起作用,因为includes 默认情况下会创建两个 SQL 查询来获取记录,并且只有在它知道你想给 @ 时才会使用 outer join 子句创建单个查询此表上的 987654328@ 子句。由于where 中的子句在这里是字符串,Rails 无法知道您要在其中使用哪些表,因此它会默认创建两个没有连接的数据库查询 - 并且出现错误。
猜你喜欢
  • 2016-08-06
  • 2011-09-02
  • 2011-04-11
  • 1970-01-01
  • 1970-01-01
  • 2016-01-23
  • 1970-01-01
相关资源
最近更新 更多