-
[Spring] default_batch_fetch_size 대로 in쿼리가 나가지 않는 이유Spring 2022. 1. 9. 02:28
개발을 하다가 이상한 상황을 봤다.
default_batch_fetch_size을 1000으로 설정했음에도 불구하고, in절이 62개의 리스트로만 가져오고 나눠서 가져오는 것이다.
버그인가 싶었는데 구글링을 해보니 이유를 찾았다. 역시 킹영한ㄷㄷ
보통 관계형 데이터베이스들은 select * from x where in (?), select * from x where in (?, ?) 같은 preparedstatement는 미리 문법을 파싱해서 최대한 캐싱을 해둔다.
그런데 default_batch_fetch_size가 1000이라면 최대 1000개의 preparedstatement을 준비해야한다.
select * from x where in (?)
select * from x where in (?, ?)
select * from x where in (?, ?, ?)
select * from x where in (?, ?, ? ...)
이렇게 되면 성능이 떨어지기 때문에 Hibernate는 이 문제를 해결하기 위해 2등분을 하며 최적화를 한다.
1000 = 설정값
500 = 1000/2
250 = 500/2
125 = 250/2
62 = 125/2
31 = 62/2
15 = 31/2
7 = 15/2...
이렇게 최적화를 하기 때문에 100개를 셀렉할 때, 62개, 31개, 7개로 끊어가져오는 이유가 여기 있었다.
너무너무 신기하다.
이 방법 외에 그냥 설정한대로 in을 전부하는 방법도 있긴하다.
spring.jpa.properties.hibernate.batch_fetch_style: dynamic
하지만 이방법은 최적화가 되지 않기 때문에 권장치는 않는다고 한다.
때문에 무작정 1000 이렇게 할게 아니라,
본인서비스의 최대 객체양이나 평균양을 고려해서 적정한 수치를 설정하는 것이 좋을 것같다.
'Spring' 카테고리의 다른 글
[Spring] spring boot 라이브러리 버전관리 (0) 2022.01.15 [Spring] MultipleBagFetchExcption 발생 시 해결 방법 (0) 2022.01.09 [Spring] 프로파일 설정을 통해 샘플데이터 추가하기 (0) 2022.01.07 [Spring] querydsl - 수정, 삭제 벌크 연산 (0) 2022.01.05 [Spring] querydsl - 동적쿼리 만드는 법 (0) 2022.01.05