1. 분리할 때의 장점?
- count 쿼리를 분리함으로써 최적화 여지를 남길 수 있다
- 예를들어 content 쿼리는 join을 여러번 걸고 조건이 복잡할 수 있으나, count 쿼리는 별개로 단순하게 구성될 수 있기에 분리함으로써 성능 개선을 도모할 수 있다.
2. 예제
@Override
public Page<MemberTeamDto> searchWithPaging(MemberSearchCond cond, Pageable pageable) {
List<MemberTeamDto> content = queryFactory
.select(
new QMemberTeamDto(
member.id,
member.username,
member.age,
team.id,
team.name
)
)
.from(member)
.leftJoin(member.team, team)
.where(
usernameEq(cond.getUsername()),
teamNameEq(cond.getTeamName()),
ageGoe(cond.getAgeGoe()),
ageLoe(cond.getAgeLoe())
)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
Long total = queryFactory
.select(member.count())
.from(member)
.leftJoin(member.team, team)
.where(
usernameEq(cond.getUsername()),
teamNameEq(cond.getTeamName()),
ageGoe(cond.getAgeGoe()),
ageLoe(cond.getAgeLoe())
)
.fetchOne();
return new PageImpl<>(content, pageable, total);
}
3. size()를 이용해서 countQuery?
long total = queryFactory
.selectFrom(member)
.leftJoin(member.team, team)
.where(
usernameEq(cond.getUsername()),
teamNameEq(cond.getTeamName()),
ageGoe(cond.getAgeGoe()),
ageLoe(cond.getAgeLoe())
)
.fetch()
.size();
- count 함수는 SQL 차원에서 지원하기 때문에 굳이 이렇게 전체 데이터를 받아온 뒤에 애플리케이션 레벨에서 별도로 size()를 호출해서 구할 필요 없고, 처음부터 카운트 쿼리를 호출하는 것이 더 좋음. 그 이유는 전체 데이터를 불러오고 나서 size()로 구하는 방식은 관리하지 않을 내용을 영속성 컨텍스트에 모두 업로드한 후에 size()를 호출하기 때문에, 단순 count를 구하기 위해서 적절치 않음.