프로젝트 API에 성능향상을 위한 JpaReopsitory 메서드 튜닝을 넣어보았다.
기존 상황:
기존 JpaRepository에서는 기본으로 제공하는findById를 통해 단건 조회를 해오고 있었던 상황
조회 쿼리문
단건 조회에 2개의 쿼리가 나가는 상황(댓글)
현상황은 1개의 댓글밖에 없어 1개의 추가 조회 쿼리가 나가지만 만약 N개의 댓글이 조회한다면 N개를 추가 쿼리 해오는 문제가 생긴다. 이 상황을 N+1 문제라고 부른다.
@Query("select distinct p from Project p join fetch p.projectReplies where p.id = :projectId")
Project findByIdFetchJoin(Integer projectId);
@Query 어노테이션으로 Project라는 클래스와 연관관계에 있는 댓글을 한방 쿼리로 붙혀오도록 튜닝하였다.
리팩토링 후 쿼리문
해당 project 엔티티에 해당하는 댓글을 한번에 join 해오는 쿼리가 나간다.
이렇게 직접 JPQL을 통해 작성하는 방식은 오탈자의 위험과 여러 테이블을 붙혀 올때 쿼리문이 길어진다는 단점이 있다.
예를 들어 댓글 하위에 대댓글까지 붙혀온다면 쿼리문이 더욱 길어지게 되는 단점이 있다는 점이다.
이러한 문제를 해결하면서 fetch join 과 같은 기능을 하는 EntityGraph를 사용하여 문제를 해결하였다.
Repository 수정
@EntityGraph(attributePaths = {"projectReplies","projectReplies.reReplyList","audit"})
Optional<Project> findById(Integer projectId);
조회 쿼리문
대댓글을 붙혀오기 위한 추가 쿼리가 발생하지만 N+1 문제가 발생하진 않고 있다.
API 응답 값
{
"code": 1,
"message": "정상적으로 처리되었습니다.",
"data": {
"id": 31,
"name": "테스트19",
"recruitStartDate": "2024-02-01",
"recruitEndDate": "2024-05-01",
"content": "테스트 데이터입니다",
"deposit": 100000,
"count": 5,
"projectReplies": [
{
"content": "참가하고 싶은데 어떻게 해야하나요",
"reReplyList": [
{
"content": "몸만 오시면 됩니다."
},
{
"content": "몸만으론 안되죠"
}
]
}
]
},
"result": true
}
'Spring' 카테고리의 다른 글
SpringSecurity 인증 (0) | 2024.03.01 |
---|---|
SpringSecurity 아키텍쳐이해하기 (0) | 2024.02.24 |
N+1 해결 (QueryDSL) (0) | 2024.02.11 |
프로젝트 QueryDSL 적용기 (0) | 2024.02.08 |
Swagger 적용 (1) | 2024.02.05 |