문제 상황: N+1 문제 발생 및 불필요한 쿼리 실행
- 기존 코드에서 워크스페이스와 멤버 정보를 조회할 때 불필요한 다중 쿼리가 실행되는 문제가 발생함.
- InviteRepository와 WorkspaceRepository에서 개별적으로 데이터를 조회하는 과정에서 N+1 문제가 발생하여 조회 성능이 저하됨.
1. 멤버 초대 조회 시 성능 개선 (InviteRepository)
수정 전
- 특정 워크스페이스에서 특정 유저들에게 보낸 초대 정보를 조회할 때, 개별적으로 유저를 조회하는 다중 쿼리가 실행됨.-
- 기존 방식에서는 findAll()을 호출한 후, 초대 대상자를 개별적으로 필터링하여 처리함.
- N+1 문제 발생: 초대된 멤버를 개별적으로 조회하는 추가 쿼리 실행됨.
수정 후
JPQL 쿼리에서 IN 조건을 활용하여 한 번의 쿼리로 여러 초대 정보를 조회
@Query("SELECT i FROM Invite i WHERE i.workspace.id = :workspaceId AND i.invitee.id IN :userIds") List<Invite> findByWorkspaceIdAndInviteeId(@Param("workspaceId") Long workspaceId, @Param("userIds") List<Long> userIds);
- IN 연산자를 활용하여 다중 유저에 대한 초대 정보를 한 번의 쿼리로 가져옴.
- 불필요한 개별 SELECT 쿼리 실행을 제거하여 쿼리 실행 횟수를 줄이고 성능을 최적화.
2. 워크스페이스의 멤버 정보 조회 성능 개선 (WorkspaceRepository)
수정 전
- 워크스페이스의 멤버 정보를 조회할 때, 워크스페이스를 가져온 후, 멤버 정보를 개별적으로 조회하는 추가 쿼리가 실행됨.
- N+1 문제 발생: findById(workspaceId) 호출 후, 관련 멤버 정보 조회 시 추가적인 SELECT 쿼리 실행.
수정 후
JPQL의 FETCH JOIN을 사용하여 워크스페이스와 멤버 정보를 한 번의 쿼리로 조회
@Query("SELECT w FROM Workspace w INNER JOIN FETCH w.members m WHERE w.id = :workspaceId") Workspace findMemberByWorkspaceId(@Param("workspaceId") Long workspaceId);
- INNER JOIN FETCH를 사용하여 워크스페이스와 멤버 정보를 한 번의 쿼리로 조회.
- Lazy Loading으로 인해 발생하는 추가적인 SELECT 쿼리 실행 방지.
- JOIN FETCH를 활용하여 연관된 엔티티를 즉시 로드하여 성능 최적화.
3. 특정 유저가 속한 워크스페이스 목록 조회 성능 개선 (WorkspaceRepository)
수정 전
- 특정 유저가 속한 워크스페이스 목록을 조회할 때, 'User → Member' 그리고 'Member → Workspace'
를 각각 조회하면서 여러 개의 SELECT 쿼리가 실행됨.
수정 후
JOIN을 활용하여 한 번의 쿼리로 워크스페이스 목록 조회
@Query("SELECT w FROM Workspace w INNER JOIN Member m ON m.workspace.id = w.id INNER JOIN User u ON u.id = m.user.id WHERE u.id = :userId") List<Workspace> findWorkspacesByUserId(@Param("userId") Long userId);
- INNER JOIN을 활용하여 User → Member → Workspace의 관계를 한 번의 쿼리로 조회.
- 기존보다 훨씬 빠르게 유저가 속한 워크스페이스 목록을 조회 가능.
- 쿼리 최적화로 DB 부하를 줄이고, 실행 속도를 개선.
'Archive > 예전 TIL' 카테고리의 다른 글
| [트러블슈팅] MyBatis Mapper가 Bean으로 등록되지 않는 런타임 에러 해결 (0) | 2025.06.28 |
|---|---|
| JPA: N+1 문제란? (0) | 2025.05.16 |
| ADMIN 권한 검증 시 에러 문제 (0) | 2025.02.11 |
| 토큰 매개 변수 이름과 HTTP 헤더 값 충돌 (0) | 2025.01.22 |
| 트러블슈팅: plus_week (0) | 2024.12.20 |