Tìm hiểu find_each, find_in_batches và in_batches

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ừ 5000
    • finish: 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ụng in_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à 1000
    • start: 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ặc delete_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. 😀

0 Shares:
1 comment
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like
Read More

Sentry for Rails

Table of Contents Hide Đặt vấn đềGiới thiệu SentryConfig Sentry cho Rails appSummary Đặt vấn đề Trong quá…
Read More

Setup slack notifications in Rails

Table of Contents Hide Setup Slack:Setup Rails: Slack là một phần mềm Worksplace sử dụng thông dụng rộng…