firstResult/maxResults specified with collection fetch; applying in memory
QueryDSL을 사용하는 도중 로컬 환경에서 테스트할 때는 발견하지 못하다가 서버 배포 단계에서 나타난 에러이다.
# 원인
일대다 관계, 혹은 컬렉션 패치 조인을 하게 된다면 데이터가 뻥튀기 되는 카테시안 곱 이 발생하게 된다. 이 때 Limit을 사용하여 페이징을 하게 된다면 데이터를 예측할 수 없기에 모든 데이터를 메모리로 가져와 처리하게 된다. 만약 데이터가 많아지게 된다면 성능에 문제가 생길 수 있다.
# 해결방안
# 1. Batch Size
# 2. 페이징 처리 후 fetchJoin
저의 경우는 두번째 방법을 사용하여 해결하였습니다.
@Override
public List<Chatroom> search(Long roomId, String condition, LocalDateTime createdAt) {
BooleanBuilder orBuilder = new BooleanBuilder()
.or(titleContains(condition))
.or(regionContains(condition))
.or(tagContains(condition));
List<Long> roomIds = queryFactory
.select(chatroom.roomId)
.from(chatroom)
.leftJoin(chatroom.tags, tag)
.where(
orBuilder,
cursorCondition(roomId, createdAt),
statusEq(Status.ACTIVE)
)
.orderBy(
chatroom.createdAt.desc(),
chatroom.roomId.desc()
)
.limit(20)
.fetch();
return queryFactory
.selectDistinct(chatroom)
.from(chatroom)
.leftJoin(chatroom.joins, join).fetchJoin()
.where(
chatroom.roomId.in(roomIds),
joinStatusEq(Status.ACTIVE)
)
.orderBy(
chatroom.createdAt.desc(),
chatroom.roomId.desc()
)
.fetch();
}
'Trouble' 카테고리의 다른 글
[TEST] 우아한 프리코스 테스트 코드 알아보기 (0) | 2024.10.26 |
---|---|
[TEST] System.out 과 System.in 의 테스트 방법 (0) | 2024.10.24 |
[Git] 첫 번째 커밋 삭제 시 reset 으로 삭제하면 안 되는 이유 (0) | 2024.08.17 |
[Lombok] @Builder 정적 가져오기 문제 (0) | 2024.08.17 |