优化查询以获得更好的性能
Optimize the query for better performance
原来我有这个功能
假设我有 百万 个帖子。
如何优化这个功能?
def fun
Post.all.each do |post|
if post.user.present?
post.active = true
else
post.active = false
end
post.save
end
end
喜欢在更少的行中执行此操作以获得更好的性能,因为这不是一个很好的方法。
Post.connection.execute \
"UPDATE posts SET active = TRUE WHERE user_id IS NOT NULL"
正确的方法是从数据库中删除 active
字段并在 Post
class:[=14= 中实现 ruby getter ]
def active
user.present?
end
这应该可以解决问题 - 而且速度很快...
Post.update_all("active = (user_id IS NOT NULL)")
这是另一个选项,它在没有任何原始 SQL 的两个查询中执行此操作(只是普通的 ol' 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 条记录的 table 上测试的速度结果:
# 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>
原来我有这个功能
假设我有 百万 个帖子。
如何优化这个功能?
def fun
Post.all.each do |post|
if post.user.present?
post.active = true
else
post.active = false
end
post.save
end
end
喜欢在更少的行中执行此操作以获得更好的性能,因为这不是一个很好的方法。
Post.connection.execute \
"UPDATE posts SET active = TRUE WHERE user_id IS NOT NULL"
正确的方法是从数据库中删除 active
字段并在 Post
class:[=14= 中实现 ruby getter ]
def active
user.present?
end
这应该可以解决问题 - 而且速度很快...
Post.update_all("active = (user_id IS NOT NULL)")
这是另一个选项,它在没有任何原始 SQL 的两个查询中执行此操作(只是普通的 ol' 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 条记录的 table 上测试的速度结果:
# 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>