2011-07-28 44 views
7

Tôi đang gặp phải những thách thức lớn về thời gian và khả năng tính toán khi thực hiện di chuyển dữ liệu lớn (khoảng 100.000 hàng). Tôi đang phát triển một dịch vụ xử lý nhiều dữ liệu trong đường ray. Mô hình của chúng tôi liên tục thay đổi khi chúng tôi nhận được nhiều hơn và nhiều hơn nữa cleaver về thiết kế của chúng tôi. Điều này dẫn đến rất nhiều sự di trú trên cơ sở dữ liệu của chúng tôi, đó là cơ sở dữ liệu Postgres 9.0. Thường thì những di chuyển này cũng bao gồm một số loại di cư trên chính dữ liệu. Hôm qua chúng tôi phát hiện ra rằng chúng tôi cần di chuyển thuộc tính 'văn bản' trên mô hình thành một mô hình riêng biệt để thuộc tính không còn chỉ là thuộc tính trên mô hình mà thay vào đó là mối quan hệ một đến nhiều.Thực hiện di chuyển dữ liệu lớn trong đường ray

di cư của tôi trông hơi như thế này:

def self.up 
    create_table :car_descriptions do |t| 
    t.integer :car_id 
    t.text :description 

    t.timestamps 
    end 

    Car.find_each do |car| 
    if car.description.present? 
     car.descriptions.build :description => car.description 
    end 
    car.save 
    end 
    remove_column :cars, :description 
end 

Bây giờ vấn đề là, rằng đây đang chạy khá chậm, và thậm chí tồi tệ hơn, nếu tôi đặt một bộ đếm, và in ra sự tiến bộ, tôi có thể thấy rằng di chuyển đang chạy chậm hơn và chậm hơn theo thời gian. Trong màn hình hoạt động của tôi, tôi có thể thấy rằng quá trình ruby ​​đang chiếm nhiều bộ nhớ hơn.

Vì vậy, câu hỏi của tôi là - có cách nào tốt hơn để thực hiện việc di chuyển dữ liệu lớn như thế này không?

Trả lời

12

Bạn không nên sử dụng ActiveRecord tại đây để di chuyển dữ liệu từ mô hình Car thành mô hình CarDescription của mình. Thay vào đó, bạn nên trả lời để chạy sql thô (chạy từ di chuyển). Trong công việc cuối cùng của tôi, chúng tôi đã có những vấn đề như vậy với dữ liệu khổng lồ, và chạy sqls thô dẫn đến di chuyển nhanh hơn nhiều (mặc dù nhanh chóng vẫn còn 5-6 giờ đôi khi). Một thực tế khác mà chúng tôi phát triển theo thời gian sau nhiều trải nghiệm cay đắng là chúng tôi luôn sao chép cơ sở dữ liệu của chúng tôi từ sản xuất đến máy chủ dàn dựng của chúng tôi và điều hành di chuyển ít nhất hai lần trên dàn dựng. Chúng tôi luôn đưa ra một số quy trình (cụ thể cho việc di chuyển), đây là một tiết kiệm thời gian rất lớn sau thực tiễn này. Đôi khi quá trình được bao gồm, tự thả một số chỉ mục, chạy quá trình di chuyển và tạo thủ công các chỉ mục đó một lần nữa.

Trong trường hợp hiện tại, sql có thể trông giống như thế này:

INSERT INTO car_descriptions(car_id, description) SELECT id, description FROM cars 

Hy vọng bạn tìm thấy nó hữu ích, cho tôi biết nếu tôi có thể thêm một cái gì đó để trả lời.

+0

Đánh bại tôi. Điều này sẽ giúp bạn tiết kiệm rất nhiều bộ nhớ. – erik

+0

Câu trả lời hay. Chúng tôi cũng đã thử điều đó và có vẻ như đó là cách tiếp cận tốt hơn nhiều. Cảm ơn những lời khuyên nhỏ về bạn kinh nghiệm của riêng :-) Tôi tìm thấy [liên kết này] (http://railsapi.com/doc/rails-v3.0.8rc1/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html#M004596) giữ một số thông tin về các phương pháp giúp làm sạch mọi thứ chỉ một chút trong mã rails của chúng tôi, khi thực hiện các câu lệnh SQL thủ công. –

+0

@Niels Sử dụng các phương pháp là những gì tôi có nghĩa là "chạy từ di chuyển" :). Thêm liên kết sẽ tốt hơn. – rubish

Các vấn đề liên quan