코딍코딍
코딩기록
코딍코딍
전체 방문자
오늘
어제
  • 분류 전체보기 (271)
    • 개발 (2)
    • Java (1)
    • 스프링 (28)
    • JPA (11)
    • Git (3)
    • 알고리즘 (160)
      • 백준 (132)
      • 프로그래머스 (8)
      • SWEA (20)
    • 토이 프로젝트 (14)
      • 간단한 Springboot CRUD (1)
      • 게시판 프로젝트 (13)
    • 알고리즘 개념정리 (8)
    • 오류 해결 (13)
    • 보류 (0)
    • AWS (5)
    • 트러블 슈팅 (0)
    • 회고 (3)
    • CS (4)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

최근 글

티스토리

hELLO · Designed By 정상우.
코딍코딍

코딩기록

JPA

batch_size대로 in쿼리 개수가 안 나가는 이유!

2023. 5. 14. 15:01

JPA를 사용할 때 N+1 문제를 해결하기 위해 default_batch_fetch_size를 설정하여 in절로 여러 개를 한 번에 가져올 수 있도록 한다.

하지만 실제 default_batch_fetch_size를 100으로 설정하고 30개의 데이터를 가져오려 하니 25개를 담은 in절 쿼리 1번 + 5개를 담은 in절 쿼리 한 번이 호출되었다.

 

Statement와 PreparedStatement

RDB의 경우 쿼리가 호출 될 때 아래의 3가지의 과정을 거친다.

1) 쿼리 문장 분석
2) 컴파일
3) 실행

Statement를 사용할 경우 매번 쿼리가 수행할 때마다 위의 3단계를 거치게 되고, PreparedStatement는 처음 한 번만 세 단 계를 거친 후 캐시에 담아 이후부턴 재사용을 한다. 그러므로 만약 동일한 쿼리를 반복적으로 수행한다면 PreparedStatment가 DB에 훨씬 적은 부하를 주며, 성능도 좋을 것이다.

 

default_batch_fetch_size 옵션

보통 RDB들은 select * from x where in (?) 와 같은 preparedstatement는 미리 문법을 파싱해서 최대한 캐싱을 해둔다.

그런데 데이터가 1개, 2개, 3개, 100개가 있으면 모두 각각 다음 처럼 최대 100개의 preparedstatement 쿼리를 만들어야 한다. 

select * from x where in (?)
select * from x where in (?, ?)
select * from x where in (?, ?, ?)
select * from x where in (?, ?, ? ...)

이렇게 되면 DB 입장에서 너무 많은 preparedstatement 쿼리를 캐싱해야 하고, 성능도 떨어지게 된다.

그래서 하이버네이트는 이 문제를 해결하기 위해 내부에서 나름 최적화를 한다. (규칙을 정하는 것)

default_batch_fetch_size: 100 (설정값)

50 = 100/2
25 = 50/2
12 = 25/2
10 = 10
9 = 9
...
1 = 1

그리고 1~10까지는 자주 사용하니 모두 설정. 이런식으로 잡아둔다.

 

그러면 기존에 100개의 preparedstatement 모양을 1~10, 12, 25, 50 ,100 해서 총 14개의 모양으로 최적화를 한다.

이렇게 해서 100으로 최대값을 설정하고, 18을 설정하면 12, 6 같이 나누어서 실행된다.

 

 

참고자료

https://jeonyoungho.github.io/posts/default_batch_fetch_size/

 

[JPA] default_batch_fetch_size

JPA를 사용할 때 N+1 문제를 해결하기 위해 default_batch_fetch_size를 설정하여 in절로 여러 개를 한 번에 가져올 수 있도록 한다.

jeonyoungho.github.io

 

'JPA' 카테고리의 다른 글

[JPA] 양방향 연관관계 순환 참조 문제 및 해결방법  (0) 2022.12.22
실전! 스프링 부트와 JPA 활용1 정리  (0) 2022.08.02
객체지향 쿼리 언어  (0) 2022.07.27
값 타입  (0) 2022.07.27
고급 매핑  (0) 2022.07.26
    'JPA' 카테고리의 다른 글
    • [JPA] 양방향 연관관계 순환 참조 문제 및 해결방법
    • 실전! 스프링 부트와 JPA 활용1 정리
    • 객체지향 쿼리 언어
    • 값 타입
    코딍코딍
    코딍코딍
    ㅎ2

    티스토리툴바