Skip to content

test(S15P11A705-284): 천만 건 읽기 경로 계획 관측 보고(BI-38) - #178

Merged
minyongP merged 2 commits into
devfrom
test/S15P11A705-284-plan-observation
Aug 4, 2026
Merged

test(S15P11A705-284): 천만 건 읽기 경로 계획 관측 보고(BI-38)#178
minyongP merged 2 commits into
devfrom
test/S15P11A705-284-plan-observation

Conversation

@minyongP

@minyongP minyongP commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

요약

283의 천만 건 볼륨 위에서 주요 읽기 경로 4종의 실행 계획을 117k 기준선과 대조했다. 규모에 정비례로 무너지는 것은 피드 최신 채널 하나이며(69배, Seq Scan), 원인은 COALESCE 정렬키다. 커서·상세 배치·지도는 규모를 통과했다.

스택 PR: base가 test/S15P11A705-283-massive-seed-bench(back#177)다. #177이 먼저 머지되어야 하며, 그때 base를 dev로 바꾼 뒤 머지한다. #177을 squash 머지하며 브랜치를 지우면 이 PR이 자동으로 닫히므로 base 변경을 먼저 할 것.

Jira (필수)

  • 키 또는 URL: S15P11A705-284

변경 사항

  • docs/backend/implements/BI-38-2026-08-03-massive-scale-plan-observation.md — 결과 표(12개 측정 × 2규모)·판정 4건·개선 후보 2건
  • loadtest/sql/explain-matrix.sql — 재실행 가능한 측정 매트릭스(두 DB에 같은 파일)
  • docs/backend/worklog/2026-08-03-S15P11A705-284-plan-observation.md

테스트 / 검증

  • ./gradlew clean check --no-daemon — BUILD SUCCESSFUL (Java 변경 없음, 문서+SQL만)

측정 방법 검증:

기준선 재구성: id <= 벤치 기준점 행만 pinlog_base로 복사
  → record 117,022 · collection 12,527 · member 3,007 (원본과 일치)
동일 대상 고정: member 2792 · collection 11736 (두 규모 공존)
콜드 조건: 1Gi 한도(compose.bench.yaml) + 컨테이너 재기동 직후
캐시 검증: 천만 건 측정 shared read > 0 (피드 9,673블록 · 지도 550블록)

핵심 결과:

피드 최신 채널(현재 코드):  117k 3.48ms → 10M 241ms   Parallel Seq Scan 664,689행
같은 채널 COALESCE 제거:    117k 1.94ms → 10M 1.66ms  ix_collection_feed, 105행
커서 깊은 페이지(keyset):   117k 0.03ms → 10M 0.03ms  완전히 평평 (BD-04 검증)
상세 배치 5쿼리 합계:       117k 0.4ms  → 10M 5.7ms   전부 인덱스

리뷰 포인트

  1. 판정 1 — COALESCE 제거를 개선 1순위로 올린 근거: 발행 컬렉션 666,066건 중 published_at IS NULL 0건 + V5 ck_collection_published_at CHECK(BD-33). 코드 수정은 이 PR 범위 밖(관측 보고형 티켓), 별도 티켓으로.
  2. 117k 기준선을 재구성 DB로 잰 방법의 타당성(BI-38 「측정 방법」·「한계」)

미결 / 후속

  • 개선 티켓 후보 1: 피드 최신 채널 COALESCE 정렬키 제거(+팔로우 채널 동반 정리)
  • 개선 티켓 후보 2: 지도 응답 상한/밀도 축소 — 2만 건 회원 응답 2.0MB 실측, 급하지 않음
  • deleted_at 부분 인덱스 판별·AI 스키마 쿼리는 범위 밖(283 합의·AI 파트 소유)

🤖 Generated with Claude Code

@minyongP minyongP added the test 테스트 추가·수정 label Aug 3, 2026
@minyongP minyongP self-assigned this Aug 3, 2026
@minyongP
minyongP marked this pull request as draft August 3, 2026 08:39
@minyongP
minyongP force-pushed the test/S15P11A705-283-massive-seed-bench branch from 96a891e to 2ab3424 Compare August 4, 2026 07:16
@minyongP
minyongP changed the base branch from test/S15P11A705-283-massive-seed-bench to dev August 4, 2026 07:19
minyongP and others added 2 commits August 4, 2026 16:20
지도의 27.3ms → 13.5ms를 "계획이 평평하다"로 적었는데 틀렸다. 계획이
갈린 것이다 — 117k는 Hash Join으로 place를 전수 해싱하고, 천만 건은
place가 24만 행이 되며 Nested Loop + place_pkey로 갈아탄다.

각 DB를 따로 콜드 재기동하고 실제 서울 뷰포트로 다시 쟀다(양쪽 397행):
117k 17.97ms(디스크 1,170블록) vs 천만 3.12ms(573블록) — 천만이 5.8배 빠르다.
규모가 커져서 빨라진 게 아니라 플래너가 원래 골라야 했던 계획으로 옮겨간
것이며, 백엔드에서 고칠 것은 없다.

첫 측정에는 측정 순서 캐시 편차가 섞여 있었다. 한계 절에 그 성질을 적고,
매트릭스 SQL 머리에 DB마다 콜드 재기동하라는 전제를 남긴다.

매트릭스에 지도를 [3a] bbox 없음 / [3b] bbox 있음(서울)으로 분리했다.
load-read.js가 bbox 없이 부르는데 이 보고서는 bbox 있는 쪽만 쟀던 불일치를
개선 후보 3으로 남긴다 — 다만 접근 경로는 동일하고 반환 행 수만 달라지므로
(697 → 397) 우선도는 낮다.

bbox 값도 전국(위도 33~39)에서 서울로 고쳤다. 전국 범위는 아무 행도
걸러내지 못해 필터 효과를 재는 의미가 없었다.

클라이언트 렌더링은 범위 밖임을 명시했다 — 마커 2만 개 렌더 비용은
2.0MB 전송보다 먼저 무너질 수 있으나 프론트 영역이다.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@minyongP
minyongP marked this pull request as ready for review August 4, 2026 07:20
@minyongP
minyongP force-pushed the test/S15P11A705-284-plan-observation branch from 48b08b0 to 14da344 Compare August 4, 2026 07:20
@minyongP
minyongP merged commit 9f72f97 into dev Aug 4, 2026
2 checks passed
@minyongP
minyongP deleted the test/S15P11A705-284-plan-observation branch August 4, 2026 07:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test 테스트 추가·수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant