2010-02-17 26 views
5

Tôi đang cố gắng xây dựng tiện ích cào sẽ cập nhật cơ sở dữ liệu của tôi thường xuyên.cơ sở dữ liệu cập nhật hàng loạt hiệu quả đường ray

Đây là mã tôi có cho đến nay:

namespace :utils do 

    # utils:update_ip 
    # Downloads the file frim <url> to the temp folder then unzips it in <file_path> 
    # 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 

Vấn đề tôi đang gặp là điều này mất một vài phút để nhập 100.000 mục cộng. Tôi muốn tìm một cách hiệu quả hơn để cập nhật cơ sở dữ liệu của mình. Lý tưởng nhất là điều này sẽ vẫn độc lập với kiểu cơ sở dữ liệu, nhưng nếu không phải máy chủ sản xuất của tôi sẽ chạy trên MySQL.

Cảm ơn bạn đã có thông tin chi tiết.

Trả lời

9

Bạn đã cố gắng sử dụng AR Extensions để nhập số lượng lớn? Bạn sẽ có được những cải tiến hiệu năng ấn tượng khi bạn chèn 1000 hàng vào DB. Truy cập vào website của họ để biết thêm chi tiết.

Tham khảo những ví dụ để biết thêm thông tin

Usage Example 1

Usage Example 2

Usage Example 3

+0

Đây là chính xác những gì tôi đang tìm kiếm, cảm ơn bạn. – codr

+0

Đá quý hỗ trợ nhập từ CSV. Điều này giúp loại bỏ chi phí xác thực và xác thực 'ActiveRecord'. Tham khảo bài viết này để biết thêm chi tiết. http://www.rubyinside.com/advent2006/17-extendingar.html –

+0

Giúp tôi - cảm ơn! – ambertch

1

Bạn có thể tạo một file văn bản với tất cả BIG bạn cần và sau đó thực hiện:

mysql -u user -p db_name < mytextfile.txt 

Không chắc chắn nếu điều này sẽ được bất kỳ nhanh hơn nhưng cũng đáng thử ...

+0

Rails tự sử dụng câu lệnh chèn SQL. - Xem nhật ký đường ray của bạn. Vì vậy, phương pháp này sẽ không được cải thiện tốc độ. –

+2

Tất nhiên Rails làm INSERTS, làm cách nào khác để thêm bản ghi vào cơ sở dữ liệu? Nhưng trong tác giả bài viết ban đầu của mình đang sử dụng phương pháp "lưu" có nhiều chi phí hơn chỉ là một lần chèn đơn giản. Tôi chắc chắn nó liên quan đến việc cam kết trên mỗi chèn, làm mô hình xác nhận, vv – Zepplock

0

Như Larry nói, sử dụng tiện ích nhập khẩu DB-cụ thể của bạn nếu các tập tin đi kèm trong các định dạng mà bạn muốn. Tuy nhiên, nếu bạn cần thao tác dữ liệu trước khi chèn, bạn có thể tạo một truy vấn INSERT duy nhất với dữ liệu cho nhiều hàng, nhanh hơn việc sử dụng truy vấn riêng cho mỗi hàng (như ActiveRecord sẽ làm). Ví dụ:

INSERT INTO iptocs (ip_from, ip_to, country_code) VALUES 
    ('xxx', 'xxx', 'xxx'), 
    ('yyy', 'yyy', 'yyy'), 
    ...; 
Các vấn đề liên quan