gpt4 book ai didi

ruby - 如何优化 ActiveRecord find_in_batches 查询?

转载 作者:数据小太阳 更新时间:2023-10-29 06:52:37 24 4
gpt4 key购买 nike

我正在使用 Rails 4.0.0 和 Ruby 2.0.0。我的 Post(如在博客文章中)模型与用户相关联,该用户具有用户的 user_name、first_name、last_name 的组合。我想迁移数据,以便通过外键(即用户 ID)将帖子关联到用户。

我在 posts 表中有大约 1100 万条记录。

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

我发现将 batch_size 降低到 20 并将 sleep(10) 增加到 sleep(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 上有索引,而 users 在 user_name 上有索引,那么这将有助于此特定查询运行得更快。

关于ruby - 如何优化 ActiveRecord find_in_batches 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36633708/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com