inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

hibernate 6.x 에서 batch size의 전략 변경하기 아는 분 있으신가요?(batch_fetch_style deprecated issue)

해결된 질문

2063

psam1017

작성한 질문수 11

1

https://www.inflearn.com/questions/34469

위 링크를 참조해보면, 이전에 hibernate 의 batch size 기본전략이 legacy 임을 알 수 있습니다.

하지만, 현재 사용 중인 hibernate 6.2 에서 @BatchSize 를 사용하면 기본적으로 dynamic 으로 조회되고 있습니다. 참고로 글로벌 설정으로 default_batch_fetch_size 를 설정해도 동일합니다.

 

    select
        ...
    from
        my_table m1_0 
    where
        m1_0.id in(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)

binding parameter [1] as [INTEGER] - [5]
binding parameter [2] as [INTEGER] - [1]
binding parameter [3] as [INTEGER] - [null]
...
binding parameter [98] as [INTEGER] - [null]
binding parameter [99] as [INTEGER] - [null]
binding parameter [100] as [INTEGER] - [null]

 

그래서 batch_fetch_style 을 직접 설정하려고 봤더니 hibernate 6.0 이후부터는 deprecated 되었고, MultiKeyLoadSizingStrategy 를 사용하라고 하네요.

 

혹시 이 MultiKeyLoadSizingStrategy 사용해보신 분 있으신가요?

또는 다른 방법으로 batch size 전략을 이전의 기본전략인 legacy 처럼 변경하신 분이나 현재 프로젝트에서 비슷한 issue 겪으신 분 있으신가요?

--

(아까 오전에 비슷한 질문 올리면서, spring.jpa.properties.hibernate.jdbc.batch_size 사용하면 되는 것 같다고 했었는데 착각이었습니다. 실제로는 n + 1 발생에 영향을 주지 않습니다.)

--

(추가)

MultiKeyLoadSizingStrategy 를 사용하는 부분은 Dialect 입니다. 이때 넘겨받는 numberOfKeys 는 지정한 BatchSize 와 동일합니다. 그리고 아래 코드에 의해 최종적으로 생성하는 ? 의 개수는 최초로 딱 1번, 1개만 생성되는 것처럼 보입니다. 그러면 코드가 dynamic 처럼 작동하는 게 이해는 가네요. 동적으로 id 의 개수에 따라 다른 PreparedStatement를 사용하는 게 아니니까요.

만약 BatchSize 를 10으로 정한 필드가 있다면, 해당 필드는 아래 코드에 의해 10(pad=false, column=1) 또는 16(pad=true, column=1) 둘 중 하나의 쿼리만 생성됩니다.

위에서 언급한 링크에서 김영한 님 설명대로라면 10 + nlog2 개의 쿼리가 생성되는 데 반해, MultiKeyLoadSizingStrategy 는 딱 하나의 쿼리만을 생성하고 재사용하는 것 같습니다. 그런데 그 쿼리의 ? 의 개수를 '잘' 정하는 거죠.

그러면 pad와 numberOfColumns 를 어떻게 바꾸느냐도 알아봐야겠네요... 그리고 최적화에 대한 새로운 패러다임? 자체도 이해할 필요가 있어 보입니다.

 

아래는 Dialect 추상클래스의 일부분입니다.

	protected final MultiKeyLoadSizingStrategy STANDARD_MULTI_KEY_LOAD_SIZING_STRATEGY = (numberOfColumns, numberOfKeys, pad) -> {
		numberOfKeys = pad ? MathHelper.ceilingPowerOfTwo( numberOfKeys ) : numberOfKeys;

		final long parameterCount = (long) numberOfColumns * numberOfKeys;
		final int limit = getParameterCountLimit();

		if ( limit > 0 ) {
			// the Dialect reported a limit -  see if the parameter count exceeds the limit
			if ( parameterCount >= limit ) {
				return limit / numberOfColumns;
			}
		}

		return numberOfKeys;
	};

--

(추가)

pad 설정은 아래와 같이 하면 됩니다. 기본값은 false 인 것 같네요.

spring.jpa.properties.hibernate.query.in_clause_parameter_padding=true

그리고, numberOfColumns 는 굳이 건드려야 할 필요는 없어보입니다.

--

결론적으로 batch_fetch_style 이 deprecated 된 이후에는 기존의 legacy 처럼 여러 개의 statement 를 만들어서 사용하지 못 하고, 각 Entity 의 batch size 를 얼마나 설정하느냐에 따라 Dialect가 그에 대응하는 딱 하나의 statement 를 만드는 것 같습니다.

hibernate6.x querydsl5.x springboot3.x jpa intellij

답변 2

0

psam1017

https://www.inflearn.com/questions/903628
--
위 질문과 관련이 있는 내용 같습니다. 답변도 위 질문의 김영한 님 답변에 포함되어 있습니다.

결론적으로 hibernate 6.2 이후부터는 여러 개의 statement 를 캐싱하지 않음으로 성능 최적화를 구현하고 있고, default_batch_fetch_size 만큼의 ? 가 생성되고, null 이 들어가는 것은 자연스러운 현상(?)이니 그냥 내버려두면 되는 것 같습니다.

자세한 원리나 이유가 궁금하신 분은 위 링크 참고하시기 바랍니다.

0

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴이에요.

Hibernate 6.x에서 batch size 전략을 변경하는 방법에 대해 찾아보셨군요.
Hibernate 6.0 이후에는 batch_fetch_style이 deprecated되었다고 하네요.
그래서 MultiKeyLoadSizingStrategy를 사용하라고 추천하고 있는데요.

MultiKeyLoadSizingStrategy를 사용해보신 분이 있는지, 또는 다른 방법으로 batch size 전략을 이전의 기본전략인 legacy로 변경하는 방법을 아시는 분이 계신지에 대한 질문이시죠.

제가 답변을 드리기 전에, 해당 질문에 대한 답변과 관련된 내용은 현재 제가 가지고 있는 정보에는 없어 보입니다. 따라서, 해당 내용에 대해 자세하게 설명해드릴 수는 없어요.

그러나, Hibernate의 최신 버전과 관련된 공식 문서나 포럼에서 관련 정보나 예시 코드를 찾아보시는 것이 좋을 것 같습니다. Hibernate의 공식 사이트나 Hibernate 커뮤니티에서 자세한 내용을 찾아보시면 도움이 될 수 있습니다.

또한, 제가 답변을 드리는 이 채널은 프로그래밍과 인프런에 관련된 질문에 답변하는 곳이기 때문에, 개발과 관련된 질문에 한해서만 답변이 가능하니 참고해주세요.

더 도움을 드리지 못해 죄송합니다. 다른 질문이 있으시면 언제든지 물어보세요. 감사합니다.

벌크연산에서 member.getAge 호출 시 영속성 컨텍스트에서 데이터를 가져오는건가요?

0

20

2

inheritance startegy 선택시 고려사항

0

21

1

Entity 동등성 비교

0

18

1

패키지 구분에 대해 궁금한게 있습니다

0

25

2

스프링부트 서버 에러나요

0

26

1

RepositoryTest의 패키지 위치가 domain인 이유

0

36

2

도메인 모델에서 관계와 규칙을 구분하는 방법

0

50

2

16 강의 메세지 retryCount의 의도

0

29

2

JPA Repository 질문이 있습니다!

1

38

2

페이지네이션 처리를 쿼리에서 하는 방식 질문

1

38

1

UserService, CertificationService 책임 분리 기준 질문

0

28

1

실무 조언 관련 질문입니다.

0

44

1

sdk 설정 오류

0

53

2

H2데이터베이스 파일 생성

0

56

2

SpringBoot 4.X에서의 Querydsl 설정

0

92

2

REQUIRES_NEW 해결 방법에 대해서 질문있습니다!!

0

31

1

오탈자 - @Transactional

0

56

1

Dto와 Entity 사용 관련 질문

0

34

2

서브쿼리 강의에서 ALL 예시 관련 질문드립니다.

0

52

2

EC2 실습 중 docker-compose / docker ps 실행 시 권한 오류 문의

2

74

1

application.properties 작성 관련 질문

0

49

2

색깔구분

0

48

3

gradlew, java -jar 로 애플리케이션 실행시키기에서

1

52

1

리액트 관련 질문이 있습니다.

0

65

2