JPA 성능 최적화 (feat. @SequenceGenerator allocationSize)
JPA 성능 최적화 (feat. @SequenceGenerator allocationSize)
JPA의 기본 키 매핑을 들여다 보던 중, SEQUENCE 전략에 대해서 이해한 내용을 정리하려고 한다.
Persistence Context에 대한 개념을 충분히 이해하고 있다는 가정하에 정리할 것이다.
우선, 기본키 매핑 전략으로 SEQUENCE를 사용하려면 @SequenceGenerator 를 생성해 주어야 한다.
@Sequence의 속성은 아래와 같다.
속성들 중, allocationSize에 집중해보자. 성능 최적화에 사용되는 속성이다.
allocationSize의 역할을 이해하려면, 먼저 SEQUECE전략의 기본적인 기본 키 매핑 과정을 이해해야한다.
- em.persist(member)가 호출 되면, member를 Persistence Context에 저장을 시도한다.
- Persistence Context에 저장을 하기위해서는, PK값이 필요하다.
- 현재 PK 매핑 전략이 SEQUECNE 전략 으로 설정되어 있으므로, 미리 만들어둔 MEMBER_SEQ_GENERATOR에서 시퀀스 값을 얻으려고 call next value for MEMBER_SEQ 을 호출한다.
JPA는 성능 최적화를 위해서 기본적으로 allocationSize가 default 50으로 설정되어 있으나,
allocationSize의 역할을 알아보기 위하여 현재는allocationSize=1로 설정했다.
- allocationSize=1 인 경우를 간단한 코드를 통해 눈으로 직접 확인해보자.
결과를 확인해보면, call next value for MEMBER_SEQ 가 3번 호출 된 것을 확인할 수 있다.
- 이번에는 allocationSize=50 인 경우를 간단한 코드를 통해 눈으로 직접 확인해보자.
결과를 확인해보면, call next value for MEMBER_SEQ 가 2번 호출 된 것을 확인할 수 있다.
allocationSize=50 일때, member를 6명 저장하려고 시도했고,
이때, call next value for MEMBER_SEQ가 위와 달리 6번이 아니라 2번 호출 된 이유는,
처음에 DB에서 SEQ를 1을 호출하면서 member1이랑 매핑을 했는데, "어? 나는 allocationSize=50인데? 뭔가 이상하다?" 라는 것을
확인하고서, "나는 51까지는 PK로 매핑해서 쓸거야!"라고 메모리에 저장해놓기 때문이다.
그러면 PersistenceContext에 저장 될 때 메모리를 이용하여 아래와 같은 방식으로 PK가 매핑된다.
DB SEQ | PK |
1 | 1 |
51 | 2 |
51 | 3 |
51 | 4 |
... | ... |
51 | 51 |
101 | 52 |
101 | 53 |
그러면, call next value for MEMBER_SEQ의 호출이 처음 2번을 제외하고는, 50의 주기로 호출 될 것이다.
설명의 자세한 부분에서 약간의 다른점이 있을 수 있으나,
기본적으로 이러한 방식으로SEQUENCE 전략에서는 call next value for MEMBER_SEQ 의 호출 횟수감소로 성능최적화를 제공한다.
반면, IDENTITY 전략(Auto_Increament)은 기본 키 생성을 DB에 위임한 전략으로,
JPA는 보통 트랜잭션 커밋 시점에 INSERT SQL을 실행하지만,
IDENTITY 전략(Auto_Increament)은 DB에 ISERT SQL을 실행한 이후에 ID 값을 알 수 있으므로,
IDENTITY 전략은 em.persist() 시점에 즉시 INSERT SQL을 실행하여 DB에서 식별자를 조회한다.