사용자 도구

사이트 도구


java:hibernate:performance

Hibernate Performance Tuning

Hibernate 성능 분석

  • QuickPerf 로 lazy loading 발생여부 확인 가능(실제로는 쿼리가 날라간 갯수를 테스트 코드로 검증가능)

Join Fetch

  • JPQL 에서 join fetch를 통해서 (inner join등 명시) N + 1 대신에 미리 join 문으로 객체를 로딩할 수 있다.

@org.hibernate.annotations.BatchSize

batch-size 설정은 OneToMany 등의 관계에서 Many쪽 Lazy Proxy 객체를 로딩할때, 한번에 로딩할 갯수를 지정한다. 예를들면 Cat 객체가 Kitten 객체의 리스트를 Lazy로 가지고 있을 때 List<Cat> 을 돌면서 getKittens()를 실행하면 각각의 Cat에 대해 한번씩 쿼리가 날라간다.(n + 1 problem)

하지만 @BatchSize(size = 10) 처럼 해당 관계에 설정을 해 두면, Kitten 객체를 로딩할 때 Cat id 10개씩 in Query로 한번에 로딩한다.

  • hibernate.default_batch_fetch_size=30 프라퍼티 형태로 일괄 지정도 가능하다.
  • OneToOne, ManyToOne Eager 에 대해서는 작동하지 않았다.
  • 지나치게 큰 값을 설정하지 말아야 한다. 30개 정도가 적당해 보이며, 쿼리 실행시간이 수십 밀리세컨드 이내로 끝날 수준으로 정하는게 좋다.

hibernate.jdbc.fetch_size

> In the first case, hibernate.jdbc.fetch_size sets the statement's fetch size within the JDBC driver, that is the number of rows fetched when there is more than a one row result on select statements. In the second case, hibernate.jdbc.batch_size determines the number of updates (inserts, updates and deletes) that are sent to the database at one time for execution.

  • fetch_size 는 result 가 여러개일 때, 한 번에 읽어올 row 수이고(단,MySQL은 항상 전체 데이터를 한방에 읽는다고함. TBD)

hibernate.jdbc.batch_size

  • batch_size 는 update(insert,update,delete) 시에 묶어서 요청할 갯수이다.
  • 이 때 sequence 기반으로 ID를 생성한다면, sequence 의 increment_size 도 동일하게 맞춰주는게 좋다.

hibernate.query.in_clause_parameter_padding=true

  • Hibernate 5.2.18 이후 버전 hibernate.query.in_clause_parameter_padding=true 항상 true로 둘 것.
  • IN 절 쿼리에 대해서 2의 제곱단위로 쿼리를 생성한다.
  • 위 옵션을 켜지 않으면, IN 절 쿼리가 Query Plan Cache를 모두 점유해서 메모리가 부족해질수 있고, 메모리가 남아돌더라도 캐시를 모두 IN 절이 점유해버리므로 별로 좋지 못하다.
  • 또한 RDBMS 의 경우 그 자체 execution plan cache 가 있는데, 이 옵션을 켜면 그에 대한 hit 율도 높아지게 된다.

Hibernate Query Plan Cache

autoCommit 을 꺼서 성능 향상시키기

  • Connection Pool 의 auto commit=false을 항상 켜고, Hibernate 에서 직접 auto commit=false 하는 것을 막아서 불필요한 setAutoCommit() 호출로 인한 성능 저하를 줄이기
아주 많은 Spring의 확장들이 auto commit=true를 가정하고 만들어져 있는 것으로 보인다.

auto commit=false 이면서 Spring Data 사용시 제대로 Transaction이 안 걸려 있으면 오동작이 발생한다. 모든 Repository 인터페이스와 Custom 구현에 @Transactional을 붙여주어야 한다.

in Hibernate 5.2.10, we introduced the hibernate.connection.provider_disables_autocommit configuration property which tells Hibernate that the underlying JDBC Connections already disabled the auto-commit mode.

Assert statement count

Index Hint

Stateless Session

  • 1st/2nd level cache 등이 없고 상태가 없는 Session 모드.

참조 문서

java/hibernate/performance.txt · 마지막으로 수정됨: 2021/09/07 17:28 저자 kwon37xi