36 lines
2.6 KiB
Plaintext
Executable File
36 lines
2.6 KiB
Plaintext
Executable File
컬렉션 fetch join + 페이징이 발행하는 조인의 실행계획 (a) — LIMIT 노드 없음
|
|
출처: FeedPersistenceIT.l4ExplainCollectionJoinHasNoLimitButEntityPagingDoes 콘솔 출력 (a)
|
|
조건: seed(100) 직후. warm buffer cache(shared read=0).
|
|
쿼리: EXPLAIN (ANALYZE, BUFFERS)
|
|
SELECT fi.*, h.* FROM feed_items fi JOIN highlights h ON h.feed_item_id = fi.id
|
|
ORDER BY fi.first_highlighted_at DESC, fi.id ASC
|
|
(fetch join `select f from FeedItemJpaEntity f join fetch f.highlights order by ...`가
|
|
페이징(setMaxResults) 시 발행하는 조인과 같은 shape — 단, SQL에 LIMIT이 붙지 않는다)
|
|
|
|
Sort (cost=293.30..297.76 rows=1782 width=1904) (actual time=1.219..1.266 rows=1961 loops=1)
|
|
Sort Key: fi.first_highlighted_at DESC, fi.id
|
|
Sort Method: quicksort Memory: 445kB
|
|
Buffers: shared hit=173
|
|
-> Hash Join (cost=12.48..197.08 rows=1782 width=1904) (actual time=0.279..0.636 rows=1961 loops=1)
|
|
Hash Cond: (h.feed_item_id = fi.id)
|
|
Buffers: shared hit=173
|
|
-> Seq Scan on highlights h (cost=0.00..179.82 rows=1782 width=710) (actual time=0.231..0.330 rows=1961 loops=1)
|
|
Buffers: shared hit=162
|
|
-> Hash (cost=11.66..11.66 rows=66 width=1194) (actual time=0.035..0.036 rows=100 loops=1)
|
|
Buckets: 1024 Batches: 1 Memory Usage: 22kB
|
|
Buffers: shared hit=11
|
|
-> Seq Scan on feed_items fi (cost=0.00..11.66 rows=66 width=1194) (actual time=0.018..0.023 rows=100 loops=1)
|
|
Buffers: shared hit=11
|
|
Planning Time: 0.135 ms
|
|
Execution Time: 1.369 ms
|
|
|
|
관찰(문서 §10):
|
|
- 계획 어디에도 Limit 노드가 없다 = DB가 페이징을 하지 않았다. 조인 결과 전체(actual rows=1961 = Σ highlights)를
|
|
quicksort로 445kB 정렬한 뒤 그대로 반환한다. 페이지 크기(20)로 자르는 일은 SQL 밖 — Hibernate가 메모리에서 한다.
|
|
- 부모 feed_items는 100행(Hash 노드)인데 Hash Join 노드 actual rows=1961(= Σ highlights, §9.3)로 부푼다 —
|
|
컬렉션 fetch join의 카테시안이 그대로다. 그 곱해진 행에 DB LIMIT을 걸면 "20개 부모"가 아니라 "20개 조인 행"을
|
|
잘라 어떤 부모는 하이라이트가 잘린 반쪽으로 로드될 위험 → 그래서 Hibernate가 LIMIT을 빼고 인메모리 페이징한다.
|
|
- Buffers: shared read=0 → warm buffer cache. cold 디스크 I/O 실행시간으로 읽지 말 것.
|
|
- Execution Time 1.369 ms는 executor 내부 시간(§6.4 caveat와 동일). 애플리케이션 지연이 아니다.
|
|
- 대조군은 l4-entity-paging-limit.txt (엔티티만 페이징 → Limit 노드 존재).
|