Khi làm việc với dữ liệu lớn trong ứng dụng Ruby on Rails, việc truy vấn và xử lý hàng loạt dữ liệu có thể trở nên phức tạp. Để giải quyết vấn đề này, Rails cung cấp các phương thức quan trọng: find_each
, find_in_batches
, in_batches
. Trong bài viết này, chúng ta sẽ tìm hiểu về cách sử dụng chúng.
1.find_each:
find_each
là một phương thức mạnh mẽ giúp bạn truy vấn và xử lý hàng loạt dữ liệu một cách hiệu quả. Thay vì lấy toàn bộ kết quả truy vấn vào bộ nhớ và xử lý cùng một lúc,find_each
cho phép bạn truy vấn từng phần dữ liệu nhỏ, tiết kiệm tài nguyên hệ thống.- Ví dụ sử dụng
find_each
:
Ruby
User.find_each(batch_size: 1000) do |user|
# Xử lý dữ liệu của user
end
Trong ví dụ trên, batch_size
xác định số lượng bản ghi được truy vấn và xử lý trong mỗi lần lặp. Điều này giúp giảm áp lực lên bộ nhớ và tăng hiệu suất xử lý.
2. find_in_batches:
find_in_batches
là một phương thức tương tự nhưfind_each
, nhưng thay vì lặp qua từng bản ghi, nó trả về từng batch (nhóm) bản ghi mà bạn có thể xử lý một cách đồng thời.- Ví dụ sử dụng
find_in_batches
:
Ruby
User.find_in_batches(batch_size: 200) do |users|
users.each do |user|
# Xử lý dữ liệu của user
end
end
- Những option được sử dụng trong find_each và find_in_batches
batch_size:
là kích thước chỉ định của batch. Mặc định là 1000.start:
Chỉ định primary_key bắt đầu trong batch, ví dụ bạn muốn lấy từ id = 5000, thì batch của bạn sẽ bắt đầu từ 5000finish:
Chỉ định giá trị primary_key để kết thúc, như ở option :start là chọn vị trị bắt đầu thì :finish sẽ là vị trị kết thúc của batch.
3. in_batches trong rails 7.1
- Các bạn có thể thấy lợi ích của việc sử dụng find_each và find_in_batches ở trên, nhưng nó có hạn chế, việc sắp xếp các record chỉ dựa vào id của bảng và theo mặc định tăng dần, chúng ta không thể sắp xếp theo các trường khác. Thật may mắn trong ở phiên bản rails 7.1 chúng ta có in_batches cho phép chúng ta sắp xếp theo các column mong muốn.
- Ví dụ, nếu bạn muốn sắp xếp các bản ghi theo cột
created_at
, bạn có thể sử dụngin_batches
như sau:
Ruby
User.in_batches(of: 1000, order: :created_at) do |batch|
batch.each do |user|
# Do something with each user
end
end
- Các option hỗ trợ trong in_batches:
of:
Số lượng bản ghi tối đa trong mỗi batch. Giá trị mặc định là 1000start:
Giá trị khóa chính của bản ghi đầu tiên trong batch. Giá trị mặc định lànil
.finish:
Giá trị khóa chính của bản ghi cuối cùng trong batch. Giá trị mặc định lànil.
order:
Cột sắp xếp các bản ghi trong batch. Giá trị mặc định lànil
.
NOTE: một vài lưu ý khi sử dụng in_batches:
- Nếu bạn không chỉ định cột sắp xếp,
in_batches
sẽ sắp xếp các bản ghi theo khóa chính của chúng. - Nếu bạn chỉ định cột sắp xếp, hãy đảm bảo rằng cột đó đã được đánh index để tối ưu hóa hiệu suất.
- Nếu bạn muốn thực hiện các thao tác cập nhật hoặc xóa trên các bản ghi, hãy đảm bảo rằng bạn đã sử dụng
update_all
hoặcdelete_all
để tránh lỗi(áp dụng cho cả find_in_batches), ví dụ:
Ruby
User.in_batches.each do |batch|
batch.update_all('age = age + 5')
batch.where('age > 25').update_all(is_married: true)
batch.where('age <= 25').delete_all
end
Hi vọng bài viết có thể giúp ích cho các bạn. Chúc các bạn luôn tìm được niềm vui khi coding. 😀
1 comment
Good job ! 👍