Files
document-haness/.agents/skills/writing-tech-log-records/examples/case-body.md
T

1.8 KiB

측정값 — 직접 측정

초기화 컬렉션 수와 총 PreparedStatement는 Hibernate Statistics, 지연은 System.nanoTime으로 읽은 값이다.

:::table id="direct-measurement" caption="N별 초기화 컬렉션 수와 총 PreparedStatement" rowHeaderColumn="1"

N 초기화 Highlight 컬렉션 총 PreparedStatement 지연 중앙값
10 10 25 32.8 ms
100 100 222 85.9 ms
1,000 1,000 2,022 193.7 ms

:::

조회량은 N에 정확히 비례했다. 여기서 N은 전체 테이블 크기가 아니라 한 요청이 반환한 FeedItem 수다.

문제가 된 조회

@Query("select fi from FeedItem fi where fi.visibility = :visibility")
Page<FeedItem> loadFeed(@Param("visibility") Visibility visibility, Pageable pageable);

:::note

같은 @ManyToOne(EAGER)라도 실행 횟수는 Persistence Context 안의 distinct 대상 수가 정한다. 애너테이션 하나로 갈리지 않는다.

:::


확인한 실행 계획

:::evidence key="feed-explain-plan" alt="Index Scan 뒤 rows=500이 찍힌 EXPLAIN 출력" caption="반복되는 자식 조회의 실행 계획" zoom="true" :::

측정의 범위와 한계

:::warning

지연 값은 이미 열린 테스트 트랜잭션 안에서 어댑터 호출만 잰 단일 스레드·warm-cache 로컬 비교값이다. HTTP 종단 지연도 운영 p99도 아니다.

:::

Hibernate Statistics가 주는 값은 획득한 PreparedStatement 수이지 SQL shape별 실행 횟수가 아니다. shape별 횟수를 원문 SQL 수준에서 확정하려면 다음 중 하나로 따로 수집해야 한다.

  • SQL 로그 또는 StatementInspector
  • datasource-proxy 또는 p6spy
  • PostgreSQL statement logging