스프링 데이터 JPA는 편리한 페이징과 정렬을 위한 기능을 제공한다.
Sort
: 정렬 기능
Pageable
: 페이징 기능(내부에 Sort 포함)
Pageable
은 인터페이스로, 실제 사용할 때는 PageRequest
객체를 사용한다.
페이징과 관련해서 다음과 같은 반환 타입이 있고, 반환 타입에 따라 추가로 count 쿼리를 호출할지 말지 결정된다.
Page
: 페이징 기능 제공을 위해 전체 데이터 건수를 조회하는 count 쿼리를 추가적으로 호출한다.
Slice
: count 쿼리를 호출하지 않고, 다음 페이지가 있는지 확인을 위해 내부적으로 limit + 1로 조회한다.
List
: count 쿼리를 호출하지 않는다. (스프링 데이터 JPA가 알아서 성능 최적화)
count 쿼리는 전체 데이터 건수를 조회하기 때문에 페이징 시 일정 개수만큼 끊어서 가져오는 select 쿼리보다 무겁다. 심지어 조인을 하며 복잡하게 조회하는 경우, 이때 count 쿼리는 더욱 무거워진다.
만약 left outer join을 하는 경우, 조인 전 후가 개수가 같다. 따라서 이 경우 select 쿼리에는 조인이 필요하겠지만, 전체 개수를 가져오는 count 쿼리에는 조인을 할 필요가 없다(where 문으로 필터링을 하지 않는다는 전제). 무거운 count 쿼리를 성능 최적화 하기 위해 다음과 같이 count 쿼리를 별도로 지정해줄 수 있다.
@Query(value = "select m from Member m left join Team t",
countQuery = "select count(m.username) from Member m")
Page<Member> findByMemberAllCountBy(Pageable pageable);