실험 목적

판교역 기준 1·5·10·30km 주변 응급실을 찾는 두 쿼리를 비교했다. 두 경로 모두 거리를 계산하고 거리순으로 정렬한다. 정렬 없는 버퍼 쿼리의 이전 성능 수치는 이 비교에 포함하지 않았다.

A — MBR + 거리: SPATIAL 인덱스의 MBR 후보 검색 → ST_Distance_Sphere 구면 거리 계산 → 지정 반경 필터 → 거리순 정렬.

B — 버퍼 + 정렬: ST_Buffer 도형에 ST_Within 포함 판정 → ST_Distance_Sphere 거리 계산 → 거리순 정렬.

측정 조건

거리식 표기 변경: 별도 선행 측정

초기 SQL은 거리식을 SELECT와 WHERE에 각각 적었다. SQL 표기만으로 실제 함수 평가 횟수를 확정할 수는 없다.

SELECT id, name,
       ST_Distance_Sphere(coordinate, ST_SRID(POINT(?, ?), 4326)) AS distance_meters
FROM emergency FORCE INDEX (idx_emergency_coordinate)
WHERE active = TRUE
  AND MBRContains(ST_GeomFromText(?, 4326, 'axis-order=long-lat'), coordinate)
  AND ST_Distance_Sphere(coordinate, ST_SRID(POINT(?, ?), 4326)) <= ?
ORDER BY distance_meters;

변경 후에는 SELECT의 거리 별칭을 HAVING에서 사용했다. 이 별칭 사용법은 MySQL 문법에 의존한다.

SELECT id, name,
       ST_Distance_Sphere(coordinate, ST_SRID(POINT(?, ?), 4326)) AS distance_meters
FROM emergency FORCE INDEX (idx_emergency_coordinate)
WHERE active = TRUE
  AND MBRContains(ST_GeomFromText(?, 4326, 'axis-order=long-lat'), coordinate)
HAVING distance_meters <= ?
ORDER BY distance_meters;

두 경로 모두 거리순 정렬을 수행했다. 아래 값은 2회 평균이며, 변경 후 처리량과 p95가 개선됐다. 측정 시점이 달라 표현식 평가 횟수만의 효과로 단정하지 않는다.

반경 초기 RPS 초기 p95(ms) 변경 RPS 변경 p95(ms)
1km 1399.55 185.26 1515.39 170.35
5km 1192.28 172.86 1257.21 171.24
10km 947.44 207.53 1038.65 188.46
30km 146.66 1259.28 174.78 1026.40

HTTP 반복별 결과

RPS는 초당 요청 수, p95는 95백분위 응답 시간(ms). 모든 케이스 실패율 0%.