500만개의 데이터를 기준으로 테스트 했습니다.

커버링 인덱스 도입

커버링 인덱스는 쿼리가 필요로 하는 모든 데이터를 인덱스에서만 읽을 수 있는 경우를 말합니다. 커버링 인덱스를 이용해 id값을 빠르게 찾고, 그 id에 해당하는 데이터들을 가져오는 방식입니다.

기존 쿼리

List<Product> products = jpaQueryFactory.selectFrom(product)
    .where(product.name.like(keyword.concat("%")))
    .orderBy(product.id.desc())
    .offset(pageable.getOffset())
    .limit(pageable.getPageSize())
    .fetch();
Long count = jpaQueryFactory.select(product.count())
    .from(product)
    .where(product.name.like(keyword.concat("%")))
    .fetchOne();

개선 쿼리

List<Long> productIds = jpaQueryFactory.select(product.id)
      .from(product)
      .where(product.name.like(keyword.concat("%")))
      .orderBy(product.id.desc())
      .offset(pageable.getOffset())
      .limit(pageable.getPageSize())
      .fetch();
List<Product> products = jpaQueryFactory.selectFrom(product)
      .where(product.id.in(productIds))
      .orderBy(getOrderSpecifiers(pageable.getSort(), product))
      .fetch();

조회 성능 비교

1. index search → 평균 8.5초

Untitled

Untitled

Untitled

Untitled

Untitled

2. covering index search → 평균 0.9초 (약 844% 빨라진 응답)

Untitled

Untitled

Untitled

Untitled