--- id: 5159c415-232d-424a-970a-b0db52746767 kind: QUESTION slug: isolate-round-trip-and-row-volume title: Round Trip과 Row Volume을 독립 측정할 것인가 topic: jpa-feed-query-performance topicName: JPA 피드 조회 성능 — N+1 진단과 조회 전략의 진화 topicName: JPA 피드 조회 성능 project: Liner N + 1문제 status: 게시 전 studio: "https://hyeonworks.com/studio/documents/5159c415-232d-424a-970a-b0db52746767/edit" questionStatus: OPEN sourceRevision: n+1liner-lab@2026-08 source: - final/document.md#4-5 - final/document.md#6-2 --- # Round Trip과 Row Volume을 독립 측정할 것인가 현재 데이터셋은 N을 키우면 반환 FeedItem 수, Highlight 총 행수, 엔티티 생성량, DB 왕복이 한꺼번에 늘어나서 지연이 늘어난 원인을 넷 중 어느 하나에 돌릴 수 없다. 변수를 하나씩 격리한 데이터셋을 만들지는 아직 정하지 않았다. ## 관계 - **JPA N+1 정량 진단 기준** 왕복 수와 전송 행수를 서로 다른 축으로 나눠 센다. - **Fetch 타입이 아니라 조회 방식이 만든 ToOne N+1** 같은 조회에서 왕복 수와 한 번에 읽어 오는 행수를 함께 확인한다. ## 사실 - 하이라이트 개수는 순위 기반 편중 분포로 생성된다. 상한 500, 하한 1이다. - 하이라이트 총량은 N에 정비례하지 않는다. N=10에서 이미 1,285개이고 그중 500개가 첫 아이템 하나에서 나오며, N을 100배인 1,000으로 키워도 2,917개에 그친다. - 컬렉션 초기화 수(collectionFetches)는 하이라이트 총량이 아니라 FeedItem 수 N에 정비례한다. - 왕복은 FeedItem 수에 비례해 늘고, 전송 행수와 엔티티 생성은 한 FeedItem이 가진 Highlight 수에 비례해 늘어난다. - 지연은 단일 스레드에서 7회 반복하고 앞 2회를 워밍업으로 버린 뒤 남은 5개 표본의 중앙값과 최댓값으로 기록했다. - 격리 데이터셋 세 종류를 계획했지만 아직 실행하지 않았다. ## 가정 - 왕복 수와 전송 행수는 지연을 서로 다른 방식으로 늘린다. - FeedItem 수만 바꾸고 FeedItem마다 Highlight를 1개로 고정하면 왕복이 지연에 얼마나 붙는지 따로 잴 수 있다. - FeedItem 수를 고정하고 Highlight 수만 바꾸면 한 번에 읽어 오는 행수가 지연을 얼마나 늘리는지 따로 볼 수 있다. ## 미지수 - 격리 데이터셋을 추가로 유지할 가치가 있는가. 시더와 테스트가 늘어난다. - FeedItem 수만 바꾼 데이터셋에서 지연이 왕복 수에 선형으로 붙는가. - Highlight 수만 바꾼 데이터셋에서 지연이 전송 행수에 비례하는가, 아니면 어느 행수부터 더 가파르게 늘어나는가. - 왕복과 행수를 갈라 재도 전략 선택이 달라지는가. 이미 배치로 왕복을 2,022개에서 23개로, 프로젝션으로 엔티티 로드를 1,569개에서 0개로 줄였다. - 편중 분포를 유지한 데이터셋과 격리 데이터셋을 모두 유지할 것인가, 격리 데이터셋으로 대체할 것인가. ## 제약 - 현재 지연 값은 단일 스레드에서 같은 JVM으로, DB 캐시가 데워진 상태에서 잰 상대값이라 절대값 비교에 쓸 수 없다. 격리 데이터셋을 만들어도 측정 조건이 같아서 이 값으로는 여전히 N에 따른 증가 방향만 말할 수 있다. - 시더가 복잡해지면 지금까지 잰 값을 다시 재현하지 못할 수 있다. 기존 데이터셋은 그대로 두고 새 데이터셋을 더한다. - 편중 분포는 실제 라이너 데이터와 같다고 주장하려고 만든 것이 아니라 일부 페이지에 하이라이트가 매우 많을 수 있다는 조건을 통제된 방식으로 재현하려고 만든 합성 분포다. 하이라이트 개수를 균일하게 두면 한 아이템에 수백 개가 몰려서 생기는 전송량과 메모리 압박도, 아이템마다 최신 3개를 뽑아야 하는 필요도 데이터셋에서 사라진다. ## 선택지 ### 1. 세 데이터셋을 모두 만든다 FeedItem 수만 바꾼 것, Highlight 수만 바꾼 것, 편중 분포를 유지한 것 세 가지를 함께 둔다. 왕복과 전송 행수가 지연을 각각 얼마나 늘리는지 따로 잴 수 있다. 시더와 테스트가 늘어나고 실행 시간도 길어진다. ### 2. 편중 데이터셋만 유지하고 격리는 하지 않는다 전략 선택이 이미 정해졌다면 원인을 갈라도 결정이 바뀌지 않는다. 현재 데이터셋으로 회귀만 지킨다. 나중에 지연 원인을 따져야 할 때 다시 만들어야 한다. ### 3. 필요할 때만 한시적으로 만든다 왕복과 행수를 갈라 봐야 하는 판단이 생겼을 때 격리 데이터셋을 만들어 측정하고 남기지 않는다. 측정할 때마다 시더를 다시 맞춰야 해서 같은 값을 다시 얻기 어렵다. ## 다음 검증 1. FeedItem을 10 / 100 / 1,000으로 바꾸고 FeedItem마다 Highlight를 정확히 1개씩 두는 데이터셋을 만든다. 2. FeedItem을 20개로 고정하고 Highlight를 1 / 10 / 100 / 500으로 바꾸는 데이터셋을 만든다. 3. 두 데이터셋에서 왕복 수, 전송 행수, 지연을 각각 측정한다. 4. 왕복 수가 늘 때와 전송 행수가 늘 때 지연이 각각 얼마나 늘어나는지 비교한다. 5. 갈라 잰 결과가 이미 내린 전략 선택을 바꾸는지 본다. 바꾸지 않는다면 격리 데이터셋을 상시 유지할지 다시 판단한다.