Activerecord-Import
Bài đăng này đã không được cập nhật trong 3 năm
Giới thiệu
Activerecord-Import là một gem dùng để insert một số lượng lớn dữ liệu một cách nhanh chóng, hiệu quả tránh các vấn đề về phải thực hiện một số lượng lớn các câu lệnh insert và vấn đề N+1
# Hãy làm một ví dụ đơn giản để hiểu hơn về tác dụng của Gem
Thử đưa vào 100,000 cuốn sách vào dữ liệu theo cấu trúc sao :
create_table :books do |t|
t.column :name, :string, null: false
t.column :description, :string
end
Chúng ta sử dụng giải pháp đơn giản sau : Đó là chuyển từ file csv thành 1 array sau đó đưa vào dữ liệu :
convert_csv_to_book_attributes.each do |attrs|
Book.create!(attrs)
end
Dĩ nhiên , nó thực hiện rất tốt nhưng bù lại nó lại tốn qúa nhiều nhiều thời gian.
Tại sao Active Record lại chậm rùa cụt chân vậy ???
Đơn giản là vì mỗi lần thực hiện create 1 record sẽ tạo ra 1 INSERT statement. 100,000 statement ??? Không những vậy , nó còn phải thực hiện mở / đóng database 100,000 cho write, update index cho table đó . Điều đó làm tốn rất nhiều tài nguyên cho hệ thống ... Khoảng 92s cho tất cả câu lệnh , Chúng ta cùng làm 1 chút thay đổi để cải thiện nó nào
Giải pháp : sử dụng gem import
Chúng ta sẽ không sử dụng CREATE nữa mà thay vào đó tạo các instance của BOOK vào 1 arrays
books = convert_csv_to_book_attributes.map do |attrs|
Book.new(attrs)
end
Thật sự đơn giản ... Sau đó chúng ta Book.import books
Mới nhìn qua, mọi người nghĩ là chắc rút gọn được vài giây là cùng ))
Nhưng thật chất nó chỉ mất khoảng 5-10s để thực hiện nhanh hơn khoảng 19 lần so với cách truyền thống . Thật đáng kinh ngạc phải không
Nhưng nó chưa phải là tất cả , vì nó còn phải validate cho mỗi lần insert vào như uniqueness chẳng hạn , rất dễ lỗi
Vậy nên để cãi thiện hơn nữa , bạn hãy thêm vào đằng sau Book.import books, validate: false
. Tốc độ sẽ là khoảng gấp 21 lần bình thường .
Mình thấy vậy vẫn chưa đủ nếu bạn chỉ thay đổi 1 column trong record đó
columns = [:title, :description]
# E.g. [ ['Book #1', 'Good book'], ['Book #2', 'Great Book'], ...]
array_of_book_attrs = convert_csv_to_book_attributes
Book.import columns, array_of_book_attrs, validate: false
Tốc độ sẽ tăng nhanh đáng kể )))
Cùng nhìn vào kết quả thực tế sau nhiều lần thử nghiệm với benchmark
Tổng kết :
Cảm ơn các bạn đã đọc hướng dẫn nho nhỏ của mình về gem import này . Mong các bạn tìm thấy sự hữu ích của nó .
Nguồn : https://www.mutuallyhuman.com/blog/2016/06/28/importing-data-quickly-in-ruby-on-rails-applications https://github.com/zdennis/activerecord-import
All rights reserved