Skip to content

notification_history 테이블에 status, deadline 복합 인덱스 추가#96

Merged
jhan0121 merged 1 commit intobe/devfrom
refactor/noti-hist-index
Apr 6, 2026
Merged

notification_history 테이블에 status, deadline 복합 인덱스 추가#96
jhan0121 merged 1 commit intobe/devfrom
refactor/noti-hist-index

Conversation

@jhan0121
Copy link
Copy Markdown
Collaborator

@jhan0121 jhan0121 commented Apr 6, 2026

🚀 작업 내용

notification_history (status, deadline) 복합 인덱스 추가

스케줄러가 매 분/5분 주기로 실행하는 두 쿼리에서 notification_history 풀스캔이 발생하는 문제 해결을 위한 인덱스 추가.

인덱스 컬럼 순서

  • status (선행): 등치 조건(= 'PENDING', = 'FAILED')
  • deadline (후행): 범위 조건(> now())

EXPLAIN 개선 결과 (더미 데이터 80,000건 기준)

쿼리 개선 전 개선 후
findAllRetryableCycles ALL, rows=79,900, filtered=11% range, rows=8,000, filtered=100%
findAllByScheduledAt ALL, rows=79,900, filtered=33% ref, rows≈24,000, filtered=100%

📸 이슈 번호

✍ 궁금한 점

  • X

@jhan0121 jhan0121 added this to the 1.1.* milestone Apr 6, 2026
@jhan0121 jhan0121 self-assigned this Apr 6, 2026
@jhan0121 jhan0121 added the ♻️ refactor 리팩토링 label Apr 6, 2026
@github-project-automation github-project-automation bot moved this to Backlog in recycle-study Apr 6, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 6, 2026

🧪 테스트 커버리지 리포트

Overall Project 96.74% 🍏

There is no coverage information present for the Files changed

Comment on lines +1 to +2
CREATE INDEX idx_nh_status_deadline
ON notification_history (status, deadline);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

인덱스 컬럼 순서 선택 (status 선행, deadline 후행)은 두 쿼리의 사용 패턴에 잘 맞습니다.

다만 두 쿼리에서 이 인덱스가 활용되는 방식이 다릅니다:

findAllRetryableCycles — 인덱스를 완전히 활용

WHERE nh.status = :status      -- status 등치 조건 → 인덱스 선두 컬럼
  AND nh.deadline > :now        -- deadline 범위 조건 → 인덱스 후행 컬럼

(status, deadline) 복합 인덱스가 두 컬럼 모두 활용되어 range 스캔으로 개선됩니다.

findAllByScheduledAtstatus prefix만 활용

WHERE rc.scheduledAt <= :scheduledAt   -- review_cycle 테이블 컬럼 (인덱스 무관)
  AND nh.status = :status              -- status 등치 조건만 해당

이 쿼리에는 deadline이 WHERE 조건에 없으므로 status prefix만 사용됩니다 (EXPLAIN의 ref 결과가 이를 반영). 해당 쿼리 단독이라면 (status) 단일 인덱스와 동일한 효과이지만, findAllRetryableCycles를 위해 deadline을 추가한 설계이므로 두 쿼리를 하나의 인덱스로 커버하는 합리적인 선택입니다.

추가로 findAllByScheduledAtrc.scheduledAt <= :scheduledAt 조건은 review_cycle 테이블을 필터링하는데, review_cycle.scheduled_at에 인덱스가 없다면 이 부분에서도 풀스캔이 발생할 수 있습니다. 데이터 규모가 커질 경우 review_cycle(scheduled_at) 인덱스도 함께 검토해보면 좋을 것 같습니다.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 6, 2026

리뷰 코멘트

스케줄러 실행 주기 설명 불일치

PR 설명에서 "매 분/60초 주기로 실행하는 두 쿼리"라고 기재되어 있으나, 실제 코드와 다릅니다.

  • findAllRetryableCycles: EmailRetryScheduler.java@Scheduled(fixedDelay = 300_000)5분 간격 실행
  • findAllByScheduledAt: ReviewEmailSender.java@Scheduled(cron = "${schedule.review-mail.cron}") → cron 표현식에 따라 결정 (60초가 맞다면 config 확인 필요)

인덱스 설계 자체는 문제없으나, PR 설명의 전제가 실제 주기와 맞는지 확인 후 업데이트하면 좋을 것 같습니다.


전반적으로

80,000건 기준 EXPLAIN 결과를 함께 제시한 점이 좋습니다. status 선행 컬럼 선택 근거(등치 조건)와 deadline 후행 컬럼(범위 조건) 순서도 인덱스 이론에 부합합니다. 시간이 지나면서 SENT 레코드가 누적될수록 PENDING/FAILED 필터의 선택도(selectivity)가 높아져 인덱스 효과가 더 커질 것으로 보입니다.

@jhan0121 jhan0121 changed the title feat: notification_history 테이블에 status, deadline 복합 인덱스 추가 notification_history 테이블에 status, deadline 복합 인덱스 추가 Apr 6, 2026
@jhan0121 jhan0121 merged commit 874f70c into be/dev Apr 6, 2026
2 checks passed
@jhan0121 jhan0121 deleted the refactor/noti-hist-index branch April 6, 2026 05:29
@github-project-automation github-project-automation bot moved this from Backlog to Done in recycle-study Apr 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

♻️ refactor 리팩토링

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant