목차

Hibernate Performance Tuning

Hibernate 성능 분석

N+1

Join Fetch

@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.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.

hibernate.jdbc.batch_size

hibernate.query.in_clause_parameter_padding=true

MySQL 의 경우 in 쿼리의 ID 갯수가 너무 크면 index 를 타지 않고, 통계를 사용하는 경우가 있다.

특히 200 개 기준인게 보통인데, in_clause_parameter_padding 은 2^n 단위로 증가하므로 128개를 초과하면 in 파라미터가 그 다음인 256 개가 돼 버리면서 인덱스를 안타게 될 수 있다.

in 에 들어가는 값이 128 을 초과하지 않게 파티셔닝하고 관리하는게 좋다. @BatchSize, hibernate.default_batch_fetch_size 도 참조.

  • eq_range_index_dive_limit : default 200 개 초과시 index 안탐.
  • range_optimizer_max_mem_size : default 8mb 초과시 index 안탐.

참조 : MySQL IN절을 통한 성능 개선 방법

Hibernate Query Plan Cache

autoCommit 을 꺼서 성능 향상시키기

아주 많은 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

참조 문서