java 배우기/TIL

N+1 문제 해결해보기

checkuu 2024. 10. 3. 23:40

 

문제

 

public List<CommentResponse> getComments(long todoId) {
    List<Comment> commentList = commentRepository.findByTodoIdWithUser(todoId);

    List<CommentResponse> dtoList = new ArrayList<>();
    for (Comment comment : commentList) {
        User user = comment.getUser();
        CommentResponse dto = new CommentResponse(
                comment.getId(),
                comment.getContents(),
                new UserResponse(user.getId(), user.getEmail())
        );
        dtoList.add(dto);
    }
    return dtoList;
}

 

comment 조회시 N+1 문제 발생

 

원인

 

User 와 Comment가 연관관계로 설정되어있고 fetchType.LAZY 로설정되어있음.

comment 조회시 반복문을 통해 getUser를 commentList의 크기만큼 호출하면서 추가쿼리가 발생

 

해결방법

 

public List<CommentResponse> getComments(long todoId) {
    List<Comment> commentList = commentRepository.findByTodoIdWithUser(todoId);

    List<CommentResponse> dtoList = new ArrayList<>();
    for (Comment comment : commentList) {
        CommentResponse dto = new CommentResponse(
                comment.getId(),
                comment.getContents(),
                new UserResponse(comment.getUser().getId(), comment.getUser().getEmail())
        );
        dtoList.add(dto);
    }
    return dtoList;
}
// @Query("SELECT c FROM Comment c JOIN c.user WHERE c.todo.id = :todoId")
@Query("SELECT c FROM Comment c JOIN fetch c.user WHERE c.todo.id = :todoId")
List<Comment> findByTodoIdWithUser(@Param("todoId") Long todoId);

 

Query 문에 join 되어있던것을 join fetch로 해주면서 user의 정보를 한번의 쿼리로 함께 가져오게 해서 n+1 문제를 해결하였다.

 

'java 배우기 > TIL' 카테고리의 다른 글

기술 면접 준비하기-2  (0) 2024.10.10
기술 면접 준비하기-1  (0) 2024.10.10
date 타입 불일치로 인한 에러  (2) 2024.10.03
포크해온 코드 분리하기  (0) 2024.10.02
CI/CD란  (0) 2024.10.02