LXD 프로젝트 중 발생한 교정 좋아요 여부 조회의 N+1 문제를 해결했던 과정을 작성하고자 합니다.
배경 사항
이와같이 작성된 교정 리스트 내, 현재 사용자가 좋아요를 눌렀는지 여부를 Frontend에 전달해야 했습니다.
하지만 이를 조회하는 과정에서 MemberSaved 테이블을 탐색하고, 전부 matching해서 값을 가져와야하는 N+1 문제가 발생했습니다.
기존 방식 : 단순 순회 + N+1 발생 가능
private boolean checkLikedByMe(Correction correction, Member currentMember) {
return correction.getSavedByMembers().stream() .anyMatch(msc -> msc.getMember().equals(currentMember)); }
개선 방안 : Bulk 좋아요 여부 조회로 전환
핵심 아이디어
- 한 번의 쿼리로 현재 유저가 좋아요한 교정 ID들만 뽑는다.
- 이후 응답을 ResponseDTO로 조립하는 단계에서 Map<CorrectionId, Boolean> 형태로 조회 여부를 빠르게 결정한다.
이러한 아이디어를 적용해 리팩토링을 진행하였습니다.
개선 코드
1. Repository 쿼리 추가
@Query("SELECT msc.correction.id FROM MemberSavedCorrection msc "
+ "WHERE msc.member = :member AND msc.correction.id IN :correctionIds")
List<Long> findLikedCorrectionIdsByMember(
@Param("member") Member member,
@Param("correctionIds") List<Long> correctionIds
);
2. Service단 Bulk 좋아요 Map 생성
public Map<Long, Boolean> findLikedByMeMap(List<Correction> corrections,
Member currentMember) {
List<Long> correctionIds = corrections.stream()
.map(Correction::getId)
.toList(); List<Long> likedIds = memberSavedCorrectionRepository.findLikedCorrectionIdsByMember(currentMember, correctionIds);
// ID → true Map 구성 return correctionIds.stream() .collect(Collectors.toMap( id -> id, id -> likedIds.contains(id) )); }
3. DTO 생성 시 빠르게 매핑
Map<Long, Boolean> likedByMeMap = findLikedByMeMap(
corrections, currentMember);
List<CorrectionDTO> results = corrections.stream()
.map(c -> CorrectionDTO.builder()
.correctionId(c.getId())
.originalText(c.getOriginalText())
.isLikedByMe(likedByMeMap.getOrDefault(c.getId(), false))
.build())
.toList();
리팩토링 후 장점
좋아요 정보 엔티티 순회 ID 기반 단건 쿼리
성능 | N+1 문제 발생 | 쿼리 1회로 해결 |
메모리 사용 | 전 유저 로딩 | 필요한 ID만 조회 |
확장성 | 낮음 | 좋아요 수/친구 여부 등 확장 쉬움 |
결론
사용자별 좋아요 여부, 북마크, 팔로우 여부 등 사용자 개별 데이터가 많아지는 API에서는
Bulk 단건 쿼리 + Map 처리 방식이 성능과 최적화 방식에서 더 낫다는 것을 깨달았습니다.
'Server > 공부' 카테고리의 다른 글
[Server/공부] GraphQL이란? REST와 비교 (4) | 2025.08.10 |
---|---|
[AI] RAG과 임베딩의 개념 : AI 챗봇 만들기 -1 (0) | 2025.07.14 |
[서버/공부] 데이터베이스 설계 및 정규화 이론 (0) | 2024.11.05 |