加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – 如何优化ActiveRecord find_in_batches查询?

发布时间:2020-12-17 04:25:12 所属栏目:百科 来源:网络整理
导读:我正在使用Rails 4.0.0和 Ruby 2.0.0.我的帖子(如在博客帖子中)模型与用户的user_name,first_name,last_name的组合相关联.我想迁移数据,以便帖子通过外键与用户关联,这是用户的ID. 我在帖子表中有大约1100万条记录. 我正在运行以下代码来使用Linux服务器上的
我正在使用Rails 4.0.0和 Ruby 2.0.0.我的帖子(如在博客帖子中)模型与用户的user_name,first_name,last_name的组合相关联.我想迁移数据,以便帖子通过外键与用户关联,这是用户的ID.

我在帖子表中有大约1100万条记录.

我正在运行以下代码来使用Linux服务器上的rake任务来迁移数据.但是,我的任务一直被服务器“杀死”,可能是由于rake任务,特别是下面的代码,消耗了太多的内存.

我发现将batch_size降低到20并将睡眠(10)增加到睡眠(60)允许任务运行更长时间,更新更多记录而不被杀死,但需要更多时间.

如何针对速度和内存使用优化此代码?

Post.where(user_id: nil).find_in_batches(batch_size: 1000) do |posts|
  puts "*** Updating batch beginning with post #{posts.first.id}..."
  sleep(10) # Hopefully,saving some memory usage.
  posts.each do |post|
    begin
      user = User.find_by(user_name: post.user_name,first_name: post.first_name,last_name: post.last_name)
      post.update(user_id: user.id)
    rescue NoMethodError => error # user could be nil,so user.id will raise a NoMethodError
      puts "No user found."
    end
  end
  puts "*** Finished batch."
end

解决方法

在数据库中完成比来回移动数据更快的工作.

这可以使用ActiveRecord完成.
当然请在重要数据释放之前对此进行测试.

Post
  .where(user_id: nil)
  .joins("inner join users on posts.user_name = users.user_name")
  .update_all("posts.user_id = users.id")

此外,如果帖子在user_id上有索引,并且用户在user_name上有索引,那么这将有助于更快地运行此特定查询.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读