我有一个rake任务,它将几个表中的所有信息累加到一个表中,每个表大约有200 000行:
task :migrate_all_info_tables_to_one => :environment do
profiles = Profile.all
profiles.each do |profile|
basic_info_items = profile.basic_info_items
basic_info_items.each do |item|
info = InfoItem.find_or_initialize_by_kind_and_value_and_link_and_description(:kind => 'info', :value => item.parameter, :link => item.link != 'none' ? item.link : nil, :description => item.value)
profile.info_items << info
end
cities = profile.cities
cities.each do |city|
city = InfoItem.find_or_initialize_by_kind_and_value_and_link_and_description(:kind => 'city', :value => city.title, :link => city.link != 'none' ? city.link : nil, :description => city.description)
profile.info_items << city
end
histories = profile.histories
histories.each do |item|
info = InfoItem.find_or_initialize_by_kind_and_value_and_link_and_description(:kind => 'history', :value => item.year, :link => item.link != 'none' ? item.link : nil, :description => item.event)
profile.info_items << info
end
contacts = profile.contacts
contacts.each do |item|
info = InfoItem.find_or_initialize_by_kind_and_value_and_link_and_description(:kind => 'contact', :value => item.parameter, :link => item.link != 'none' ? item.link : nil, :description => item.value)
profile.info_items << info
end
end
end
我在表中添加了所有必要的索引(使用mysql 5.1.6),每个单独的查询形式mysql需要0.00秒,从ruby控制台也是如此。但是当我运行这个rake任务时,它每分钟只处理100个配置文件记录,为什么或者我做错了?
P.S:我这样做是因为我在项目数据库架构中犯了一个错误。
答案 0 :(得分:1)
如果您在Profile上有相关记录,并且在循环遍历所有配置文件时正在访问它们,则ActiveRecord可能会为每个配置文件单独选择,并使用BEGIN和COMMIT完成。即使每次选择都非常快,这也会减慢速度。
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
查看关于热切加载关联的部分。
答案 1 :(得分:1)
为了提高效率,您可以急切加载脚本中使用的配置文件关系,使用:
Profile.includes(:basic_info_items, :cities, :histories, :contacts).all
而不是Profile.all
。
您可能还想使用Profile.find_each
代替Profile.all
,以避免在内存中加载所有个人资料。