N+1 문제가 뭔가요?

박재성·2025년 1월 6일
0

Spring

목록 보기
2/4

📌N+1 문제가 뭔가요?

N+1 문제는 데이터베이스를 사용하는 애플리케이션에서 자주 발생하는 성능 문제 중 하나예요. 보통 ORM(Object-Relational Mapping) 도구를 사용할 때 많이 나타나는데요, 쉽게 말해서 1개의 쿼리를 실행했는데 그 결과로 인해 추가적인 N개의 쿼리가 더 실행되는 상황을 의미해요.리가 실행될 거예요. 이게 바로 N+1 문제예요.

⭐왜 발생하나요?

N+1 문제는 주로 ORM이 연관 데이터를 가져오는 방식 때문에 발생해요. 보통 개발자가 명시적으로 연관 데이터를 미리 로딩(Fetch Join)하지 않으면, ORM이 각 데이터를 개별적으로 쿼리해서 가져오게 돼요.

🌟아래는 Java의 JPA를 사용하는 코드 예시예요

List<Post> posts = postRepository.findAll(); // 게시글 목록 가져오기
for (Post post : posts) {
    System.out.println(post.getComments()); // 각 게시글의 댓글 가져오기
}

위 코드는 findAll로 게시글을 한 번에 가져온 다음, 각 게시글의 getComments()를 호출하면서 N번의 쿼리를 추가로 실행하게 돼요. 데이터가 많아질수록 쿼리 수가 기하급수적으로 늘어나겠죠?

⭐어떻게 해결할 수 있나요?

🌟Fetch Join 사용하기

가장 일반적인 해결 방법은 Fetch Join을 사용하는 거예요. JPA에서는 연관된 데이터를 한 번의 쿼리로 가져올 수 있도록 Fetch Join을 지원해요.

@Query("SELECT p FROM Post p JOIN FETCH p.comments")
List<Post> findAllWithComments();

이렇게 하면 게시글과 댓글을 한 번의 쿼리로 가져올 수 있어요. 성능이 훨씬 좋아지겠죠?

🌟EntityGraph 사용하기

JPA에서는 @EntityGraph를 사용해서 필요한 연관 데이터를 미리 로딩할 수도 있어요.

@EntityGraph(attributePaths = {"comments"})
@Query("SELECT p FROM Post p")
List<Post> findAllWithComments();

🌟Batch Fetching 설정하기

Hibernate를 사용한다면 Batch Fetching을 설정해 N+1 문제를 완화할 수 있어요. Batch Fetching은 연관 데이터를 한 번에 묶어서 가져오는 방법이에요.

hibernate.default_batch_fetch_size=10

이렇게 설정하면 각 배치에 포함된 데이터는 한 번의 쿼리로 가져오게 돼요.

0개의 댓글