N+1 쿼리는 Rails 애플리케이션 성능에 치명적이므로, 효과적인 감지 및 해결이 필수적입니다.
N+1 쿼리 감지
-
로그 확인: 개발 환경
log/development.log에서 반복되는 쿼리를 통해 N+1 징후를 파악합니다. -
Bullet Gem 활용:
bulletGem은 N+1 쿼리를 자동으로 감지하여 브라우저나 콘솔에 알림을 제공합니다.Gemfile추가 및 개발 환경 설정을 통해 실시간 피드백을 받을 수 있습니다.
N+1 쿼리 해결: Eager Loading
Eager Loading은 연관 레코드를 단일 쿼리 또는 최소한의 쿼리로 미리 가져오도록 Rails에 지시합니다.
-
.includes사용: 가장 효과적인 방법으로,Post.includes(:comments)와 같이 사용하면LEFT OUTER JOIN을 통해 연관 레코드를 함께 로드하여 쿼리 수를 획기적으로 줄여줍니다. 예를 들어, 10개 게시물에 대해 11개 쿼리 대신 단 2개 쿼리로 처리 가능합니다. -
.joins및.preload:.joins: 연관 데이터를 기반으로 필터링/정렬 시 사용하며INNER JOIN을 수행합니다..preload:JOIN없이 연관 레코드 로드가 필요할 때 사용합니다..includes는 상황에 따라 적절한 방식을 자동으로 선택합니다.
흔한 실수 및 실제 적용
-
컨트롤러/뷰에서 Eager Loading 누락, 또는 중첩된 연관 관계(
Post.includes(comments: :user)) 처리 누락 시 N+1 문제가 발생합니다. -
과도한 Eager Loading은 불필요한 데이터 로드로 인해 성능 저하를 유발할 수 있습니다.
-
블로그 게시물과 댓글 렌더링 시,
@posts = Post.all대신@posts = Post.includes(:comments)를 사용하면 N+1 쿼리를 방지하고 성능을 크게 개선할 수 있습니다.