Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

JPASQL

studentList = findByGroupInfoName("학생")

SELECT * FROM user ui left join spring.group_info gi

on gi.group_id = ui.group_id and gi.name="학생"

-- 위구문을 어플리케이션사용하기위해서는 실제는

몇가지 더 변환과정이 필요합니다.

dataset = runsql(..)

javaobj = datasetToObj(result)

jsonobj = objToJson(javaobj)

앞장에서 이미 설명된 컨셉이며, JPA가 SQL에 비해 어플리케이션에서 단순하고 일관성있게 사용하는지

보여주는 예입니다. 반환타잎은 Java오브젝트뿐만아니라,웹에서 바로 사용가능한 Json 결과로 뿌려줄수 있기떄문에

사용코드내에서 사용자정보에서 학생정보만 추출하는 과정이 이 한줄이외에 더 추가되는것은 JPA에서

개발 생산성 낭비로 측정하고 있습니다.  하지만 SQL문을 직접 작성하지 않을뿐

이러한 JPA 인터페이스가 어떤 SQL문으로 변환되어 실행이 되고 실제 데이터베이스에서

실행계획이 어떻게 되는지점검할 필요가 있습니다.

...

JPA에 익숙하다면, 자신이 작성한 함수 인터페이스가, 어떠한 SQL문으로 변환되어 작동이 될지 

예측할수도 있지만, JPA를 믿지 못하겠다고 가정해봅시다.

이럴때 아래옵션을 통해, 함수호출시마다 SQL문을 확인할수가 있습니다.


JPA-SQL문 Trace

  • spring.jpa.properties.hibernate.show_sql=true
  • spring.jpa.properties.hibernate.use_sql_comments=true
  • spring.jpa.properties.hibernate.format_sql=true

...

어플리케이션 레벨에서 쿼리에관련된 TestCase 작성을 쉽게하고 또한 실제 작동되는 SQL문도 체크할수 있습니다.

반복작업에 드는 개발시간을 최대한 줄이고, 유닛테스트를 활용하는데 전환할수가 소모적 반복적 SQL문 작성시간을 줄이고, 유닛테스트로 전환될수 있을 가능성을 확인할수 있습니다.



실행계획 조사하기

Trace된 SQL문을 그대로 복사하여, 실행계획을 조사합니다. 매번 이러한 과정을 거칠필요는 없을듯보이며

SQL방식이던 JPA방식이던..., 성능에 의심이가는 부분에대해서는 개발방식과는 별개로 측정되고 분석되어야하는

사항입니다.

실행계획의 출력포맺은 DB마다 다르지만 공통적인 3가지요소가 있습니다.

...

적은량의 데이터에서 탐색시 효과가 없을수 있으나,  데이터량이 늘어남에따라 효과를볼수가 있습니다.

프로그래밍 모델에서 간단하게

List<String>  VS  BTree<Key>  VS Map<int> 

위 세가지 자료 구조의 접근 차이 라고 보면 될듯합니다. 

List는 순차 풀스캔, BTree사용의 경우 이진트리탐색 , Map 의경우 해시를 통한 탐색


스캔 범위/방식에따른 실행계획 전략

성능을 위한 스캔 범위 Type은 3가지정도로 요약할수 있습니다.

  • 이중루프(Nested Loops) : 한쪽테이블을 읽으면서 결합조건에 맞는 레코드를 다른쪽에서 모두 찾음
  • Sort Merge : 결합할 두 테이블을 정렬을 하고 순차적으로 결합
  • Hash : 결합 키값을 해시로 맵핑

...

DB접근을 최소화하는 전략을 택할수 있으며...


간단하게 설명을하면...

No Format
User user1 = findByName("Minsu");

...


User user2 = findByName("Minsu");

...


user1.GetName()

...


user2.GetName()

위와같은 코드는 일반적인 SQL/SP 호출 어플케이션에서는, 두번의 Select문을 DB에게 요청을 하였을것입니다.

JPA에서는 JPA에서는 기본적으로 , 동일 트랙잰션에서 위와같은 위와같이 동일처리라고 판단되는 사항에대해

SELECT SQL한번만 조회를하고, DB 호출없이 오브젝트 재사용전략을 택합니다.

DB에서는 상황에따라 옵티마이져가 불필요한 IO를 접근하지 않고, 캐시메모리를 활용할수 있지만있는 상황입니다.

JPA 어플리케이션 레이아웃은레이아웃에서는, SQL호출 자체도 하지 않는다는 않겠다는 의미입니다.

어플리케이션에서 이러한 장치가 없으면 SELECT SQL을 두번  호출하였을것입니다.

물론 JPA에서 지연로딩같은 특수한 기능은 JPA사용이 중복 호출실수를 잡아주는 기능은 아니며라이브러리는 아니기때문에

어플케이션 레이아웃에서 관여하는 성능에 관련된 몇가지 JPA컨셉을  추가로 학습을 해야합니다오히려 이러한 메카니즘을 정확하게 파악해야함을 의미합니다.

Read전략

...

  • 즉시읽기( Eager loading) : 
  • 지연읽기 ( Lazy loading ) :

영속성 전이 전략

...

  • ALL : 부모의 변화가 자식에게 모두 전가
  • PERSIST : 부모의 영속화 될때 자식도 영속화가됨
  • MERGE : 트랜젝션이 종료되고 변경사항이 merge()수행시 변경사항적용
  • REMOVE : 부모삭제시 연관된 자식도 삭제
  • REFRESH : 부모가 변경되면 자식도 변경
  • DETACH : 부모가 DETACH되면, 연관된 ENTITY도 DEATCH되어 변경반영 죽시 안됨
  • orphanRemoval : 연관관계가 끊어진 자식을 자동으로 제거

...

JPA는 객체지향과 데이터모델링 사이에 간극을 최소화하고 편리한 방식임에는 분명하지만

튜닝 관점을 쿼리에서 JPA에서 제공하는 레이어활용으로 전환을 하려면

개발 난이도를 줄였다라고 판단할수는 없을듯 합니다. 

오히려 SQL/SP 중심적으로 개발했을때 보다, 더 깊이 RDB를 이해하고 학습해야 되지 않나란 생각을 해봅니다중간에 새로 생긴 계층을 잘 활용하기위해서는 더 많은 DB병행 학습이 필요할수도 있습니다.


참고: http://zzong.net/post/15