Active Record의 대규모 데이터 처리: find_each와 find_in_batches 비교

find_each vs find_in_batches in Active Record

작성자
발행일
2025년 05월 06일

핵심 요약

  • 1 find_each는 레코드를 하나씩 처리하되 내부적으로 배치 단위로 가져와 메모리 효율성을 높이며 개별 레코드 작업에 적합합니다.
  • 2 find_in_batches는 레코드 배열(배치) 단위로 처리하여 그룹 단위 로직, 대량 삽입, CSV 추출 등 전체 그룹 작업에 유용합니다.
  • 3 두 메서드 모두 대규모 데이터셋 처리 시 메모리 사용량을 최적화하지만, `.order(:id)` 없이는 순서를 보장하지 않으며 반복 중 데이터 변경에 유의해야 합니다.

도입

Rails 애플리케이션에서 대규모 데이터셋을 다룰 때, 모든 레코드를 메모리에 한 번에 로드하는 것은 비효율적이며 시스템 성능 저하를 초래할 수 있습니다. Active Record는 이러한 문제를 해결하기 위해 `find_each`와 `find_in_batches`라는 두 가지 강력한 배치 처리 메서드를 제공합니다. 이 메서드들은 메모리 사용량을 효율적으로 관리하면서 대량의 레코드를 순회할 수 있도록 돕습니다.

Active Record의 배치 처리 메서드인 find_eachfind_in_batches는 각각 다른 방식으로 대규모 데이터셋을 처리합니다.

find_each

find_each는 겉으로는 레코드를 하나씩 순회하는 것처럼 보이지만, 실제로는 내부적으로 지정된 batch_size (기본값 1000개)만큼 레코드를 배치로 가져와 처리합니다.

  • 특징:
    • 기본적으로 1,000개 단위로 레코드를 가져옵니다.
    • 블록 내에서는 한 번에 하나의 레코드에 접근합니다.
    • 각 개별 레코드에 동일한 작업을 수행할 때 매우 효율적입니다.
  • 예시: ruby User.find_each(batch_size: 1000) do |user| user.send_weekly_email end

find_in_batches

find_in_batchesfind_each와 달리, 각 배치를 레코드 배열 형태로 블록에 전달합니다. 이를 통해 그룹 단위로 레코드를 처리할 수 있습니다.

  • 특징:
    • 배치당 레코드의 전체 배열을 받습니다.
    • 대량 삽입, CSV 내보내기, 그룹화된 분석 등 전체 그룹에 대한 작업을 수행할 때 이상적입니다.
  • 예시: ruby User.find_in_batches(batch_size: 1000) do |users| users.each { |user| user.send_weekly_email } end

사용 시기

  • find_each 사용 시기:
    • 레코드를 개별적으로 처리할 때.
    • 간결하고 깔끔한 코드를 선호할 때.
    • 레코드당 메모리 효율성이 중요할 때.
  • find_in_batches 사용 시기:
    • 전체 배치를 한 번에 처리해야 할 때.
    • 그룹화된 로직(예: 데이터 요약)을 수행할 때.
    • 데이터베이스 왕복 횟수를 줄여 성능을 최적화할 때.

결론

find_each와 find_in_batches는 Rails 개발에서 대규모 데이터셋을 다루는 데 필수적인 Active Record 메서드입니다. 이들은 메모리 사용량을 최소화하면서 효율적인 데이터 처리를 가능하게 하여 애플리케이션의 성능과 안정성을 향상시킵니다. 그러나 두 메서드 모두 `.order(:id)`를 명시하지 않으면 순서를 보장하지 않으며, 반복 중에 레코드를 수정하거나 삭제할 경우 데이터 일관성 문제를 야기할 수 있으므로 주의 깊게 사용해야 합니다. 적절한 메서드 선택은 특정 작업의 요구사항과 성능 목표에 따라 달라집니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!