주의점
성능개선
Test 기준
@Override
public Slice<MemberSimpleResponseDto> getFollowersLegacy(Pageable pageable, String memberId, String prevMemberId) {
List<MemberSimpleResponseDto> content = jpaQueryFactory.select(Projections.constructor(MemberSimpleResponseDto.class,
member.memberId,
member.nickname,
member.profileImage,
member.feature
)).from(follow)
.join(member)
.on(follow.from.eq(member))
.where(follow.to.memberId.eq(memberId))
.orderBy(member.memberId.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize()+1)
.fetch();
boolean hasNext = content.size() > pageable.getPageSize(); // 뒤에 더 있는지 확인
content = hasNext ? content.subList(0, pageable.getPageSize()) : content; // 뒤에 더 있으면 1개 더 가져온거 빼고 넘긴다
return new SliceImpl<>(content, pageable, hasNext);
}
@Override
public Slice<MemberSimpleResponseDto> getFollowers(Pageable pageable, String memberId, String prevMemberId) {
List<MemberSimpleResponseDto> content = jpaQueryFactory.select(Projections.constructor(MemberSimpleResponseDto.class,
member.memberId,
member.nickname,
member.profileImage,
member.feature
)).from(follow)
.join(member)
.on(follow.from.eq(member))
.where( ltMemberId(prevMemberId),
follow.to.memberId.eq(memberId)
).orderBy(member.memberId.desc())
.limit(pageable.getPageSize()+1)
.fetch();
boolean hasNext = content.size() > pageable.getPageSize(); // 뒤에 더 있는지 확인
content = hasNext ? content.subList(0, pageable.getPageSize()) : content; // 뒤에 더 있으면 1개 더 가져온거 빼고 넘긴다
return new SliceImpl<>(content, pageable, hasNext);
}
private BooleanExpression gtMemberId(String prevMemberId) {
if (prevMemberId == null) return null; // prevMember가 주어지지 않으면 null로 where 조건 무시됨
return member.memberId.gt(prevMemberId); //마지막으로 리턴된 prevMemberId 다음부터 탐색
}
@Test
@Transactional
void noOffset(){
// memberId가 멤버99가 멤버 989보다 뒤에있다. 그러나 이건 제대로 된 결과이다! PK 기준으로 정렬하는 것은 가능하다
Long srt = System.currentTimeMillis();
FollowerRequestDto req = FollowerRequestDto.builder().pageNo(98).pageSize(10).build();
Slice<MemberSimpleResponseDto> legacy =
followRepository.getFollowersLegacy(PageRequest.of(req.getPageNo(), req.getPageSize()), "멤버1000", req.getPrevMemberId());
log.info("legacy : {}",System.currentTimeMillis() - srt);
log.info("{}", legacy.getContent().get(9).getMemberId());
assertThat(legacy.getContent().size()).isEqualTo(10);
Long srt2 = System.currentTimeMillis();
Slice<MemberSimpleResponseDto> noOffset =
followService.getFollower(
FollowerRequestDto.builder().pageNo(0).pageSize(10).prevMemberId("멤버990").build(), "멤버1000");
log.info("noOffset : {}",System.currentTimeMillis() - srt2);
log.info("{}", noOffset.getContent().get(0).getMemberId());
assertThat(noOffset.getContent().size()).isEqualTo(10);
}
2024-01-23T16:23:45.197+09:00 INFO 16816 --- [ main] c.a.c.member.service.FollowServiceTest : legacy : 482ms
2024-01-23T16:23:45.199+09:00 INFO 16816 --- [ main] c.a.c.member.service.FollowServiceTest : noOffset : 2ms