ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JPA 장인께서 소개하는 MySQL 사용시 JPA 성능 향상 방법 9가지-번역
    Jpa 2020. 10. 28. 21:34

    먼저 이 글은 백기선님의 블로그 ( www.whiteship.me/ ) 을 보다가 알게된 블로그 출처: vladmihalcea.com/9-high-performance-tips-when-using-mysql-with-jpa-and-hibernate/ 의 글을 번역한 내용입니다. 

     

    하이버네이트를 사용하면서 MySql 의 성능 최적화를 할지에 대한 고민을 해봤다면 한번쯤 원본을 읽어보길 바란다. 

     

     

     

     

     

    High Performance Tip in MySql with JPA & Hibernate

    JPA & Hibernate 를 MySQL 에 사용할 때 성능 향상 팁

    Introduction

     

    모든 관계형 데이터베이스의 고유한 SQL 표준 스탠다드가 있지만, 우리가 관계형 데이터베이스를 최대한 효율적으로 사용하기 위해서는 데이터 접근 레이어(Data Access Layer) 를 관리하여야 한다. 

     

    이 글에서는 여러분들이  MySql 과 Hibernate을 사용할 때, 퍼포먼스를 최대치로 끌어올리는 방법에 대해서 다루겠습니다. 

     

    1.JPA Table 기본키 생성 시 Auto Identifier Generator Type을 사용하지 마라

     

    모드 엔티티에서는 유니크한 식별자를 필요로 한데, JPA 그리고 Hibernate 는 여러분들에게 엔티티의 식별자를 만들어주는 3개의 전략을 제공해줍니다.

     

    • IDENTITY

    • SEQUENCE

    • TABLE

     

    다수의 데이터베이스의 커넥션이 증가할 때, 테이블은 식별자 전략을 높이지 않습니다.

     참조 : (https://vladmihalcea.com/why-you-should-never-use-the-table-identifier-generator-with-jpa-and-hibernate/

    한가지 더, 데이터베이스 한개의 커넥션에서도 AUTO 전략은 IDENTITY, SEQUENCE 보다, 10배정도의 시간이 더 들게 됩니다. 

     

    만약 AUTO 전략을 사용하게 되신다면, Hibernate는 정말 쓰레기같은 퍼포먼스를 선보이게 됩니다.

    물론 AUTO일 때도 성능 최적화 이슈를 해결할 수 있습니다. 

    참조 :  https://vladmihalcea.com/why-should-not-use-the-auto-jpa-generationtype-with-mysql-and-hibernate/

    • Native Generator는 Table을 대신에서 identity를 픽함. 

     

     

    2.IDENTITY generator는 JDBC batch 삽입이 불가능하다. 

     

    MySql 5.7 과 8.0에서 Sequence를 지원해주지 않기 때문에, 우리느 무조건 Identity를 사용할 것이다. 하지만 이 글에서 말하 듯, JDBC batch insert의 사용을 hibernate가 막아버리게 되는데,

    JDBC Batch는 Update와 Delete는  아무런 영향을 주지 않는데, 오직 INSERT만 막아버리게 된다. 이유는 영속성컨텍스트 (Persistence Context)가 Flush진행이 되었을 때, 

    INSERT 문은 이미 실행이 되어버렸을 것이다. 

     

    이 이슈에 대한 해결은, 무조건 JDBC batch insert를 다른 프레임워크(JOOQ)에서 실행시켜야 한다. 

     

     

    3.Docker와, tmpfs를 통해 통합 테스트 성능을 향상시켜라

     

    MySql 과 MariaDB에서 DB스키마를 날려버리거나, 다시 테스팅 돌릴 통합테스트를 다시 만들 때, 치를 떨게하는 느린 속도를 가지고 있다. 하지만, 우리는 Docker와 tmpfs 를 통해서 쉽게 해결할 수 있는데, 

     

    이 글에서 , 메모리 안에서 데이터 폴더를 매핑 시키면서, 통합 테스트 환경을 거의 H2, HSQLDB 과 같이 속도를 향상 시킬 수 있다.

     

     

    4.비정형 데이터는(non - structed data)는 JSON을 사용하자

     

    우리가 RDBMS 사용하면서 비정형 데이터를 저장해야할일이 왕왕 생기고는 한다. 

    • JSON형태로 클라이언트에서 온 데이터는 파싱하고, isnert 해야한다.

    • 재 처리를 저장하기 위해 캐시 할 수있는 이미지 처리 결과

     

    비록 Native하게 지원하지는 않지만, Jsom Column을  Java object로 또는, Jackson JsonNode로 쉽게 매핑할 수 있다.

     

    또, Custom Type을 따로 적을 필요도 없이 Maven에 끌어 쓰기만 하면된다. 요로코롬

     

    5.DB Round Trip은 Stored Procedure를 사용하자

     

    엄청나게 많은 데이터들을 다룰 때, Database 밖으로, 데이터를 옮기는건 정말 효율적이지 않다. Stored Procedure라고 불리는 Database 기능을 사용하면, 더욱더 효과적인데, 

     

    좀 더 자세히, JPA, Hibernate에서 Stored Procedure를 어떻게 사용하는지 확인해보자.



    6. ResultSet 스트리밍을 사용할 때 조심하자

     

    SQL 의 스트리밍은 2계층 어플리케이션 구조에 훌륭하다. 만약 우리가 resultset을 스트리밍 할 때, JDBCDriver에 대한 이해도가 필요하다. Mysql에서 Database 커서 기능을 사용할 때, 





     

     

    이 둘중 하나를 선택해야 한다. 하지만, 웹기반 어플리케이션을 에서, Pagination이 더 작합하다. 

    JPA 2.2에서 java 1.8 스트림 을 지원한다. 

     




    7.항상 DataBase 트렌젝션은 종료 시켜라

     

    관계형 데이터베이스 에서, 모든 쿼리문들은 database 트랜잭션 내에서 실행하게 된다. 그러므로 트랜적션은 선택권이 아니게 되는데,

     

    하지만 우리는 우리가 트랜잭션이 커밋이 되든 롤백이 되든, 최신 트랜잭션은 항상 종료시켜야 한다. 종료시키는 걸 잊어버리면, 나중에  락이 걸려서 아무것도 할 수 없게 된다. 








    8.날짜와 시간을 을 다루는 건 쉽지 않다. 

     

    • 인코딩 다루기 (Handling encodings)

    • 여러 타임존에서 날짜와 시간 다루기 (Handling Date/Time across multiple Time Zones)

     

    여기 프로그래밍 에서 까다로운 두가지가 있다. 

     

    두 번째 문제를 해결하려면 모든 타임 스탬프를 UTC 시간대로 저장하는 것이 좋은데, 하지만, MySql Connector/ J 8.0 이전에 우리는 useLegacyDatetimeCode JDBC 드라이버 Configuration Property 도 False로 지정해줘야 한다. MySQL Connector/ J 8.0 에는 그렇게 할 필요는 없어졌다. 

         9. PreparedStatements might be emulated

    (번역 못함)

    Although you might that, since Hibernate uses PreparedStatements by default, all statements are executed like this:

    In reality, they are executed more like this:

    As I explained in this article unless you set the useServerPrepStmts MySQL JDBC Driver property, PreparedStatements are going to be emulated at the JDBC Driver level to save one extra database roundtrip.

     

     

    Conclusion

     

     다음 글을 보고, Jpa & Hibernate 를 사용하면서 생각보다 명심해야 할 것들이 꽤 많은 것을 알 수 있다. MySql 은 현재 대부분 웹앱에서 가장 많이 배포된 RDBMS 중 하나이기 때문에, 다음 노하우를 알고 Data Access Layer를 조정하여 잘 활용하는 것이 매우 중요하다. 

     

    'Jpa' 카테고리의 다른 글

    JPA @OneToOne 매핑이 안된다고? Unique  (0) 2020.11.04

    댓글

Designed by Tistory.