□ 전체 QueryDsl 코드
- MySQL의 공간인덱스를 사용하기 위해 Point타입을 사용
@Override
public Page<GymSimpleResponse> search(String name, String address, GymType gymType,
Point userLocation, Double requestDistance, Pageable pageable) {
BooleanExpression condition = buildSearchCondition(
name, address, gymType, userLocation, requestDistance);
NumberTemplate<Double> distanceTemplate = Expressions.numberTemplate(
Double.class,
"ST_Distance_Sphere({0}, {1})", gym.location, userLocation
);
JPAQuery<Tuple> query = jpaQueryFactory
.select(gym, distanceTemplate)
.from(gym)
.where(condition)
.orderBy(distanceTemplate.asc());
// 페이지로 변환
List<GymSimpleResponse> gymResponses = query
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch()
.stream()
.map(tuple -> new GymSimpleResponse(
tuple.get(gym).getName(),
tuple.get(gym).getRegionAddress(),
Double.valueOf(String.format("%.1f", tuple.get(distanceTemplate) / 1000))
))
.filter(gymSimpleResponse -> gymSimpleResponse.getDistance() <= requestDistance)
.collect(Collectors.toList());
long total = query.fetchCount();
return new PageImpl<>(gymResponses, pageable, total);
}
□ 개선 전
- ST_Distance_Sphere() : 두 좌표 사이 구형 거리를 구하는 함수
NumberTemplate<Double> distanceTemplate = Expressions.numberTemplate(
Double.class,
"ST_Distance_Sphere({0}, {1})", gym.location, userLocation
);
- NumberTemplate<T> : QueryDSL의 숫자 표현 클래스, Double을 타입으로 지정하여 표현식의 결과가 Double 타입임을 나타냄
- Expressions.numberTemplate(Class, Template) : 표현식을 생성하는 정적 메서드, NumberTemplate을 생성하며, SQL 함수나 특정 데이터베이스 함수와 같은 맞춤형 표현식을 만들 수 있다.
- 성능
테스트환경
|
응답속도 | |||
최초 | 증가 | 최종 |
시간
|
v3 |
1 | 0 | 1 |
30s
|
576.94 |
10 | 0 | 10 | 1465.33 | |
10 | 10 | 100 | 10953.74 |
- 쿼리 실행계획
□ 개선 후
- ST_Contains(ST_Buffer(), Point) : 하나의 공간 객체 다른 공간객체에 포함되는지 확인하는 함수
Expressions.booleanTemplate("ST_CONTAINS(ST_Buffer({0}, {1}), {2})",
userLocation, requestDistance, gym.location
)
- Boolean을 통해 범위 내 포함되는지 확인
- ST_Contains() : 하나의 공간객체가 다른 공간객체를 포함하는지 확인
- ST_Buffer() : 지정한 지점에 일정한 반경의 버퍼를 생성
- userLocation기준 requestDistaqnce크기의 Buffer를 생성 후 gym.location이 포함되는지를 확인
※ ST_Contains는 공간 인덱스(Spatial Index)를 활용할 수 있으므로 성능 향상 기대
- 성능
테스트 환경 | 응답속도 | |||
최초 | 증가 | 최종 | 시간 | v4 |
1 | 0 | 1 |
30s
|
157.1 |
10 | 0 | 10 | 125.88 | |
10 | 10 | 100 | 165.58 |
- 쿼리 실행계획
□ 성능비교
최소 3.6배, 부하에 따라 더욱 향상된 성능을 보여준다
테스트환경 | 응답속도(ms) |
성능차이
|
||||
최초 | 증가 | 최종 | 시간 | v3 | v4 | |
1 | 0 | 1 |
30s
|
576.94 | 157.1 | 367.24% |
10 | 0 | 10 | 1465.33 | 125.88 | 1164.07% | |
10 | 10 | 100 | 10953.74 | 165.58 | 6615.38% |