사용자 도구

사이트 도구


java:hibernate:performance

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
다음 판
이전 판
java:hibernate:performance [2021/09/07 17:28]
kwon37xi [Hibernate 성능 분석]
java:hibernate:performance [2024/03/04 12:47] (현재)
kwon37xi [@org.hibernate.annotations.BatchSize]
줄 11: 줄 11:
   * [[java:quickperf|QuickPerf]] 로 lazy loading 발생여부 확인 가능(실제로는 쿼리가 날라간 갯수를 테스트 코드로 검증가능)   * [[java:quickperf|QuickPerf]] 로 lazy loading 발생여부 확인 가능(실제로는 쿼리가 날라간 갯수를 테스트 코드로 검증가능)
  
-==== Join Fetch ==== +===== N+1 ===== 
-  * JPQL 에서 ''join fetch''를 통해서 (inner join등 명시) N + 1 대신에 미리 join 문으로 객체를 로딩할 수 있다.+  * [[https://github.com/adgadev/jplusone|adgadev/jplusone: Tool for automatic detection and asserting "N+1 SELECT problem" occurences in JPA based Spring Boot Java applications and finding origin of JPA issued SQL statements in general]] 
 +  * https://stackoverflow.com/questions/97197/what-is-the-n1-selects-problem-in-orm-object-relational-mapping/39696775?stw=2#39696775 
 +  * [[https://github.com/vladmihalcea/db-util/tree/master/scripts/ramdisk/windows|vladmihalcea/db-util: If you are using JPA and Hibernate, this tool can auto-detect N+1 query issues during testing.]]
  
 +===== Join Fetch =====
 +  * JPQL 에서 ''join fetch''를 통해서 (inner join등 명시) N + 1 대신에 미리 join 문으로 객체를 로딩할 수 있다.
 +  * 하지만 **1:N 관계에서 1측이 N 만큼 반복 조회되는 문제가 있다. 실제 엔티티 객체가 여러개 생성된다.**
 +  * **limit 을 걸더라도 limit 이 DB에 걸리지 않고 모두 조회후 메모리에 걸리게 된다.**
 +  * 따라서 ''@BatchSize''나 ''default_batch_size'' 를 지정하고, join fetch 보다는 ''Hibernate.initialize(lazy로딩객체)'' 형태를 사용하는게 더 나을 수 있다. 이 경우에는 1+1 번 조회가 나가는 편이다(batch size에 따라 달라짐. batch size 단위로 조회 반복).
 +  * see [[java:hibernate:gotchas|Hibernate/JPA Gotcha]]
 +  * [[java:hibernate:configuration|Hibernate Configurations]] - ''hibernate.query.fail_on_pagination_over_collection_fetch=true'' 옵션을 켜서 미리 에러를 내고 확인해서 고쳐두는게 좋다.
 ===== @org.hibernate.annotations.BatchSize ===== ===== @org.hibernate.annotations.BatchSize =====
 ''batch-size'' 설정은 **OneToMany** 등의 관계에서 Many쪽 Lazy Proxy 객체를 로딩할때, 한번에 로딩할 갯수를 지정한다. ''batch-size'' 설정은 **OneToMany** 등의 관계에서 Many쪽 Lazy Proxy 객체를 로딩할때, 한번에 로딩할 갯수를 지정한다.
줄 22: 줄 31:
   * ''hibernate.default_batch_fetch_size=30'' 프라퍼티 형태로 일괄 지정도 가능하다.   * ''hibernate.default_batch_fetch_size=30'' 프라퍼티 형태로 일괄 지정도 가능하다.
   * OneToOne, ManyToOne  Eager 에 대해서는 작동하지 않았다.   * OneToOne, ManyToOne  Eager 에 대해서는 작동하지 않았다.
-  * 지나치게 큰 값을 설정하지 말아야 한다. 30개 정도가 적당해 보이며, 쿼리 실행시간이 수십 밀리세컨드 이내로 끝날 수준으로 정하는게 좋다.+  * 지나치게 큰 값을 설정하지 말아야 한다. 30개 정도가 적당해 보이며, 쿼리 실행시간이 수십 밀리세컨드 이내로 끝날 수준으로 정하는게 좋다. ''128''은 넘기지 말자. ''128''을 넘기는 순간 ''2^n''에 증가 규칙에 의해 ''256''개로 증가해버린다.
  
 ===== hibernate.jdbc.fetch_size ===== ===== hibernate.jdbc.fetch_size =====
줄 37: 줄 46:
   * ''IN'' 절 쿼리에 대해서 2의 제곱단위로 쿼리를 생성한다.   * ''IN'' 절 쿼리에 대해서 2의 제곱단위로 쿼리를 생성한다.
   * [[https://vladmihalcea.com/improve-statement-caching-efficiency-in-clause-parameter-padding/|How to improve statement caching efficiency with IN clause parameter padding - Vlad Mihalcea]]   * [[https://vladmihalcea.com/improve-statement-caching-efficiency-in-clause-parameter-padding/|How to improve statement caching efficiency with IN clause parameter padding - Vlad Mihalcea]]
-  * 위 옵션을 켜지 않으면, ''IN'' 절 쿼리가 Query Plan Cache를 모두 점유해서 메모리가 부족해질수 있고, 메모리가 남아돌더라도 캐시를 모두 ''IN'' 절이 점유해버리므로 별로 좋지 못하다.+  * 위 옵션을 켜지 않으면, ''IN'' 절 쿼리가 ''QueryPlanCache''를 모두 점유해서 메모리가 부족해질수 있고, 메모리가 남아돌더라도 캐시를 모두 ''IN'' 절이 점유해버리므로 별로 좋지 못하다.
   * 또한 RDBMS 의 경우 그 자체 execution plan cache 가 있는데, 이 옵션을 켜면 그에 대한 hit 율도 높아지게 된다.   * 또한 RDBMS 의 경우 그 자체 execution plan cache 가 있는데, 이 옵션을 켜면 그에 대한 hit 율도 높아지게 된다.
 +<note warning>
 +[[database:mysql|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 안탐.
 +
 +참조 : [[https://jojoldu.tistory.com/565|MySQL IN절을 통한 성능 개선 방법]]
 +</note>
 ===== Hibernate Query Plan Cache ===== ===== Hibernate Query Plan Cache =====
   * [[https://vladmihalcea.com/hibernate-query-plan-cache/|A beginner’s guide to the Hibernate JPQL and Native Query Plan Cache - Vlad Mihalcea]]   * [[https://vladmihalcea.com/hibernate-query-plan-cache/|A beginner’s guide to the Hibernate JPQL and Native Query Plan Cache - Vlad Mihalcea]]
줄 60: 줄 80:
   * [[springframework:springboot:2|SpringBoot 2]] 부터는 커넥션 풀의 ''auto-commit'' 설정값에 따라 자동으로 ''hibernate.connection.provider_disables_autocommit: true'' 설정을 해준다.    * [[springframework:springboot:2|SpringBoot 2]] 부터는 커넥션 풀의 ''auto-commit'' 설정값에 따라 자동으로 ''hibernate.connection.provider_disables_autocommit: true'' 설정을 해준다. 
     * [[https://github.com/spring-projects/spring-boot/issues/9261|Consider disabling auto-commit when wiring connection pool configs and setting hibernate.connection.provider_disables_autocommit for resource-local transactions · Issue #9261 · spring-projects/spring-boot]]     * [[https://github.com/spring-projects/spring-boot/issues/9261|Consider disabling auto-commit when wiring connection pool configs and setting hibernate.connection.provider_disables_autocommit for resource-local transactions · Issue #9261 · spring-projects/spring-boot]]
 +    * https://github.com/spring-projects/spring-boot/pull/9737
     * ''HibernateJpaConfiguration.java'' <code java>     * ''HibernateJpaConfiguration.java'' <code java>
 if (!vendorProperties.containsKey(PROVIDER_DISABLES_AUTOCOMMIT)) {  if (!vendorProperties.containsKey(PROVIDER_DISABLES_AUTOCOMMIT)) { 
줄 102: 줄 123:
   * [[https://dzone.com/articles/best-performance-practices-for-hibernate-5-and-spr-2|Best Performance Practices for Hibernate 5 and Spring Boot 2 (Part 4) - DZone Java]]   * [[https://dzone.com/articles/best-performance-practices-for-hibernate-5-and-spr-2|Best Performance Practices for Hibernate 5 and Spring Boot 2 (Part 4) - DZone Java]]
   * [[https://dzone.com/articles/think-twice-whether-you-need-hibernate|Think Twice Whether You Need Hibernate - DZone Java]]   * [[https://dzone.com/articles/think-twice-whether-you-need-hibernate|Think Twice Whether You Need Hibernate - DZone Java]]
 +  * [[https://thorben-janssen.com/tips-to-boost-your-hibernate-performance/|Hibernate Performance Tuning Tips - 2022 Edition]]
java/hibernate/performance.1631003289.txt.gz · 마지막으로 수정됨: 2021/09/07 17:28 저자 kwon37xi