Versions Compared

Key

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

...

UNION에서 중복은 제거된다라는 속성은 중요한 내용이며, 지정된 전체필드에서 중복을 찾는다란 것은

아주 큰 비용이드는 연산이 될것입니다. 중복을 무시할시 UNION ALL을 사용합니다.


그럼 UNION수행이 UNION수행을 JPA에서는 어떻게 작동되는지 구현해야하는지 확인해보겠습니다.


JPA에서 UNION 사용하기

아쉽게도 JPQL에서 UNION쿼리를 지원하지 않으며, 유니온된 결과 역시Entity에 정의하지 않은

새로운 튜플이기 때문에, SQL 맵핑처리도 원활하지 않습니다.

Native 쿼리 방식을 사용해야하며

사용방식에 만족스럽지는 못하지만 맵핑에도 어려움이 있어서

사용하여 오브젝트를 변환하는 전통적인 방법을 그대로 사용해해보겠습니다.

...

Warning

UNION과같이 JPQL이 지원하지 않는 명령문에서 JPA에서 바람직하게 어플리케이션의 엔티티와

맵핑하는 기능은 사용할수 활용 할수 없어보입니다.

어렵게 맵핑할수 있는 방식도 있지만 ( UNION JPA ENTITY ECLIPSE LINK 등으로 검색하면 됩니다.)

준비해야할 코드들이 너무 많습니다.


UNION 은 특성상 ,모든 테이블을 합쳐서 처리하는 배치성에서 많이 사용되며 편리합니다사용되곤 합니다.

모든것을 간단하게 합할수 있지만 데이터량에 따라 메모리풀의 위험성을 가지고 있으며,

이부분에 대한 튜닝을 위해 어렵고, 코드가 길어지는 SQL문 작성능력및 트랜젝션처리가 요구되기도 합니다.


JPA에서는 대량의 데이터를 안전하게 부분처리를 하는 패턴을 간단하게 설계할수 있으며

아래 아티컬을 참조합니다. 물론 이주제는 배치와 연관된내용으로 UNION과는 직접적인 상관어없습니다.

https://memorynotfound.com/hibernate-jpa-batch-insert-batch-update-example/

...

JOINUNION

  • 두개의 필드가 모두 합해지는 병렬조합
  • 필드명이 모두 합해져서,동일 필드명 사용에 유의해야합니다.
  • 엔티티가 다른 관계도가 있는 두 테이블을 하나의 결과로 만들때 사용됩니다.
  • 상하(직렬)조합이며,
  • 합하려는 양쪽 필드의 개수가 동일해야함
  • 컬럼명은 첫번째 선택된 테이블의 컬럼명에 영향받음
  • 전체행 중복제거 연산(Distinct)이 수행되기 때문에 성능에 유의
  • 엔티티가 유사한 결과 테이블을 하나의 결과로 만들때 사용됩니다.



윈도우 함수

MYSQL 5,6에서는 5에서는 윈도우 함수가 지원되지 않아, Postgres 를 이용하였습니다. 

윈도우처리는 논리적인 파티셔닝을 의미하며, MYSQL에서 PARTITION이란 키워드는

성능을 위한 실제 물리적인 파티셔닝을  의미해서 동일한 역활을 하는 쿼리를 찾기가 어려웠습니다.

Oracle과 SQL문호환성이 높은 Postgres DB를 추가로 설정하였으며

다중DB 환경설정 다중DB 환경설정 에서 두가지 DB를 설정하여 운영하는 방법을 정리하였으니 참고하세요 

...

Group ByPARTITION BY
SELECT t.address,count(*) FROM address t GROUP BY addressSELECT name,address,COUNT(*) OVER(PARTITION BY address) FROM address

자르기 기능과 동시에 집계기능이 수행되어 원래의 데이터에서

요약 집계 처리가 됩니다.

GroupBy와 비교를 하면, 집계기능을 사용하기위해 요약처리가 안되고

레코드수를 그대로 유지하면서 원하는 집계수를 볼수가 있으며

자르기 기능만 수행되었다라고 보시면됩니다.

이해를 돕기위해 색상으로 데이터를 사각형 분리를하였으며

논리적으로 파티션 혹은 자른 사각형이 윈도우같다고 하여 윈도우처리

되었다라고 표현됩니다.


나이 많은순으로 랭크를 내고자 한다고하면, 윈도우함수인 RANK()를 활용하면 간단하게 구할수있습니다.

이 기능은 Group BY와 BY및 서브쿼리와 결합하여 구현하거나 어플리케이션내에서 랭킹을 부여하는

방법으로 구현 할수도 있겠으나,DB가 지원한다고 하면 윈도우함수 사용이 권장됩니다.


postgresql기준으로 더 자세한 윈도우함수 종류와 사용방법을 살펴볼수 있습니다.

https://www.postgresql.org/docs/10/static/functions-window.html

...

이와 같이 윈도우 함수는  복잡한 집계및 집약처리에 유용하게 사용이되며, 성능계에서 특히 효율적인 집계를 위해

유용하게 사용이됩니다, 하지만  . 호환성의 관점에서는 Group BY에의한 집계 함수는

대부분의 DB에서 표준으로 사용가능하지만  논리적인 파티션 (Mysql에서 파티션은 물리적 파티션의 의미로 사용됩니다.) 기능인 윈도우함수는 SQL표준이 모두 적용이 안되어 있으며

안되어있으며 DB마다 사용방법과 지원함수가 각각 틀려서 JPA에서 표준인터페이스가 존재하지 않으며, ORM이란 특성에도 적합하지 않는

명령문입니다. 그래서 윈도우함수는 네이티브 SQL로 사용하거나 JPQL을 사용하기위해서는 방언 설정이 필요하게됩니다.

...

만약 사용하는 DB가 윈도우함수를 지원하지 못하고, 유사한 기능수행을 위해 성능이 느린 SQL문 작성을 요구될시작성이 요구될수도있습니다.

이경우 데이터베이스로부터 랭킹 데이터를 랭킹 소스는 데이터베이스로부터 Read를 하고 어플리케이션 레벨에서 랭킹을 할당하는 방식을 구현해보겠습니다.

...

Note

윈도우 함수를 사용하지 않고, 우리가 원하는 랭킹처리를하였습니다.

항상 권장되는 방식은 아니며, SQL 영역에서는 SQL문작성을 못해서

어플리케이션에서 절차식 으로 처리하는 사고방식을 초보라고 언급하기도 합니다.

하지만 이것은 SQL방식과 유사한 식을 사용한 선언형방식이며

실제 데이터베이스 내에서 윈도우 랭크함수가 작동될 구현체를

어플리케이션에서 동일하게유사하게 구현을 하였습니다.


단일 성능이 누가 더 빠르냐? 랭킹기능을 어플리케이션이 분담하여 처리하느냐? 는

각각 다른문제이며 이러한 성능 문제에 촛첨이 맞추어줘야 한다고 봅니다.

단순하게 DBMS에서 수행할수 있는 영역을 어플리케이션이 절차식으로 풀었다고

초보로 정의하는것은 바람직하지 않습니다. 어쨋든

SQL문 학습과 함께, 어플리케이션에서 데이터 가공을 람다식으로 하는것은 절차식 사고방식을 벗어나

SQL작성과 비슷한 선언형 사고방식을 하는것으로 람다식을 같이 연습하는것을 추천합니다.

...