Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

건강차트 데이터 조회 로직 개선 #96

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from

Conversation

13wjdgk
Copy link
Contributor

@13wjdgk 13wjdgk commented Jul 16, 2024

Changes 📝

건강차트 데이터 조회 로직 개선
ExerciseGuide 인덱스 추가

Details 🌼

  1. 건강 차트 조회 로직 개선

기존 로직

  • HealthMetric 테이블에서 3번 따로 조회 (혈당, 체중, 걸음수)
  • MongoDB / ExerciseGuide 컬렉션에서 1번 조회 (운동 소모 칼로리)
public HealthMetricChartResponse findHealthMetricChart(String oauthId, LocalDate startDate, LocalDate endDate) {
		List<BloodSugarMinMax> bloodSugarMinMaxes = findBloodSugarMinMaxes(oauthId, startDate, endDate);
		List<HealthMetricChartData> weights = findWeights(oauthId, startDate, endDate);
		List<HealthMetricChartData> stepCounts = findStepCounts(oauthId, startDate, endDate);
		List<HealthMetricChartData> exerciseCalories = findExerciseCalories(oauthId, startDate, endDate);
return new HealthMetricChartResponse(startDate, endDate, bloodSugarMinMaxes, weights, stepCounts, exerciseCalories);

개선 로직

  • HealthMetric 테이블에서 1번 조회 (유저의 모든 건강 데이터를 한번에 조회) + 조회된 데이터에서 혈당,체중,걸음수 필터링해서 따로 데이터를 가공
  • MongoDB / ExerciseGuide 컬렉션에서 1번 조회 (운동 소모 칼로리)
public HealthMetricChartResponse findHealthMetricChart(String oauthId, LocalDate startDate, LocalDate endDate) {
List<HealthMetric> healthMetrics = healthMetricSearchService.findAllHealthMetricByDate(oauthId, startDate, endDate);
		List<BloodSugarMinMax> bloodSugarMinMaxes = findBloodSugarMinMaxes(healthMetrics);
		List<HealthMetricChartData> weights = findWeights(healthMetrics);
		List<HealthMetricChartData> stepCounts = findStepCounts(healthMetrics);
		List<HealthMetricChartData> exerciseCalories = findExerciseCalories(oauthId, startDate, endDate);
return new HealthMetricChartResponse(startDate, endDate, bloodSugarMinMaxes, weights, stepCounts, exerciseCalories);

개선 후 성능 측정 결과

  • 서버 비용을 고려하여 , 로컬에서 테스트 했습니다
  기존 로직 개선 로직
TPS(5분 측정) 81.4 97.2
MTT(5분 측정) 1223ms 1021ms
TPS(10분 측정) 57 62
MTT(10분 측정) 1740ms 1579ms
  1. ExerciseGuide 인덱스 추가

문제 발견
운동 소모 칼로리 데이터 조회가, 다른 건강 지표 데이터 조회의 2배 이상 걸리는 것을 확인

  • Mysql의 HealthMetric 테이블 조회 : 76ms
  • MongoDB의 ExerciseGuide 컬랙션 조회 : 169ms

원인

  • 실행계획을 통해 원인을 분석
  • Mysql은 PK를 통해 인덱스로 접근하는 대신, MongoDB는 적절한 인덱스가 설정되지 않아 Mysql의 HealthMetric 테이블에 비해 조회 속도가 느림
    • Mysql 실행계획에서는 PRIMARY 인덱스를 사용하여 쿼리를 실행한 것을 확인
    • MongoDB에서는 인덱스 없이 COLLSCAN 컬렉션 스캔을 이용하여, 모든 문서를 순차적으로 조회

해결

  • 복합 필드 인덱스를 생성
  • exerciseGuide 컬렉션은 oauthId와 createdAt을 기준으로 데이터를 조회하는 경우가 대부분이고 , 두개의 필드는 수정되는 경우가 없기때문에 인덱스에 적절하다.

개선 후 성능 측정 결과

  기존 개선 후
TPS(5분 측정) 97.2 261
MTT(5분 측정) 1021ms 380ms
TPS(10분 측정) 62 279
MTT(10분 측정) 1579ms 354ms

아직 개발 DB에 인덱스 추가는 반영하지 않았습니다.

Check List ☑️

  • 테스트 코드를 통과했다.
  • merge할 브랜치의 위치를 확인했다. (main ❌)
  • Assignee를 지정했다.
  • Label을 지정했다.

[Optional] Etc

Reference 등 추가적인 내용이 있을 경우 작성합니다. 이외에는 Etc를 삭제합니다.

(일정 기간 내 사용자의 모든 건강지표 조회 후, 내부 메서드로 혈당,체중,걸음수,소모 칼로리 구분해서 Response 데이터로 가공)
@13wjdgk 13wjdgk self-assigned this Jul 16, 2024
@13wjdgk 13wjdgk added the refactoring 리팩토링 label Jul 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
refactoring 리팩토링
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant