优化查询以获得更好的性能

时间:2017-12-13 16:03:32

标签: ruby-on-rails ruby performance ruby-on-rails-4 query-performance

所以我有这个功能。

假设我有数百万的帖子。

如何优化此功能?

def fun
  Post.all.each do |post|
    if post.user.present?
       post.active = true
    else
       post.active = false
    end
    post.save
  end
end

就像这样做更少,更好的性能,因为这不是一个非常好的方法。

3 个答案:

答案 0 :(得分:5)

这应该可以解决问题 - 而且它很快......

Post.update_all("active = (user_id IS NOT NULL)")

答案 1 :(得分:3)

这是另一个选项,可以在没有任何原始SQL的两个查询中执行它(只是简单的'Rails):

Post.where(user_id: nil).update_all(active: false)
Post.where.not(user_id: nil).update_all(active: true)

而且,不管你信不信,这实际上在数据库中运行得比在一个使用表达式active = (user_id IS NOT NULL)的查询中运行更快,以填充active

以下是在只有20,000条记录的表格上测试的速度结果:

# Single (expression-based) query
<Benchmark::Tms:0x00007fd251a52780 @cstime=0.0, @cutime=0.0, @label="", @real=2.3656239999982063, @stime=0.0, @total=0.009999999999999787, @utime=0.009999999999999787>

# Two (purely column-based) queries
<Benchmark::Tms:0x00007fd2518c36d0 @cstime=0.0, @cutime=0.0, @label="", @real=2.309347999995225, @stime=0.0, @total=0.0, @utime=0.0>

答案 2 :(得分:2)

Post.connection.execute \
  "UPDATE posts SET active = TRUE WHERE user_id IS NOT NULL"

正确的方法是从数据库中删除active字段并在Post类中实现ruby getter:

def active
  user.present?
end