高效批量更新rails数据库

我正在尝试构建一个rake实用程序,它会经常更新我的数据库。

这是我到目前为止的代码:

namespace :utils do # utils:update_ip # Downloads the file frim  to the temp folder then unzips it in  # Then updates the database. desc "Update ip-to-country database" task :update_ip => :environment do require 'open-uri' require 'zip/zipfilesystem' require 'csv' file_name = "ip-to-country.csv" file_path = "#{RAILS_ROOT}/db/" + file_name url = 'http://ip-to-country.webhosting.info/downloads/ip-to-country.csv.zip' #check last time we updated the database. mod_time = '' mod_time = File.new(file_path).mtime.httpdate if File.exists? file_path begin puts 'Downloading update...' #send conditional GET to server zipped_file = open(url, {'If-Modified-Since' => mod_time}) rescue OpenURI::HTTPError => the_error if the_error.io.status[0] == '304' puts 'Nothing to update.' else puts 'HTTPError: ' + the_error.message end else # file was downloaded without error. Rails.logger.info 'ip-to-coutry: Remote database was last updated: ' + zipped_file.meta['last-modified'] delay = Time.now - zipped_file.last_modified Rails.logger.info "ip-to-country: Database was outdated for: #{delay} seconds (#{delay / 60 / 60 / 24 } days)" puts 'Unzipping...' File.delete(file_path) if File.exists? file_path Zip::ZipFile.open(zipped_file.path) do |zipfile| zipfile.extract(file_name, file_path) end Iptocs.delete_all puts "Importing new database..." # TODO: way, way too heavy find a better solution. CSV.open(file_path, 'r') do |row| ip = Iptocs.new( :ip_from => row.shift, :ip_to => row.shift, :country_code2 => row.shift, :country_code3 => row.shift, :country_name => row.shift) ip.save end #CSV puts "Complete." end #begin-resuce end #task end #namespace 

我遇到的问题是,这需要几分钟才能输入10万多个条目。 我想找到一种更有效的方式来更新我的数据库。 理想情况下,这将保持独立于数据库类型,但如果不是,我的生产服务器将在MySQL上运行。

感谢您的任何见解。

您是否尝试过使用AR Extensions进行批量导入? 当您向数据库插入1000行时,您可以获得令人印象深刻的性能改进。 访问他们的网站了解更多详情。

有关更多信息,请参阅这些示例

用法例1

用法例2

用法例3

使用数据库级实用程序来实现高速Luke!

不幸的是,它们是特定于数据库的。 但它们很快对于mysql,请参阅http://dev.mysql.com/doc/refman/5.1/en/load-data.html

您可以生成包含所需INSERT的文本文件,然后执行:

 mysql -u user -p db_name < mytextfile.txt 

不确定这是否会更快但值得一试......

我目前正在尝试使用activerecord-import,听起来很有希望:

https://github.com/zdennis/activerecord-import

正如Larry所说,如果文件采用您想要的格式,请使用特定于数据库的导入实用程序。 但是,如果需要在插入之前操作数据,则可以生成包含多行数据的单个INSERT查询,这比为每行使用单独的查询要快(如ActiveRecord所做的那样)。 例如:

 INSERT INTO iptocs (ip_from, ip_to, country_code) VALUES ('xxx', 'xxx', 'xxx'), ('yyy', 'yyy', 'yyy'), ...;