본문 바로가기

IT

[SQL] Union과 Union all 차이

2개 이상의 별도의 조회 쿼리 결과 값을 한번에 보고 싶을 때 UNION과 UNION ALL을 쓰게 된다.
A, B라는 조회데이터 집합이 있다고 한다면 UNION은 합집합 역할을 해준다고 생각하면 된다.


UNION 종류

1. UNION(UNION DISTINCT) : 중복값 제외하여 출력 (A∪B - A∩B) [일반적으로 사용하는 UNION은 UNION DISTINCT의 줄임입니다.]
2. UNION ALL : 중복 상관없이 출력  (A∪B)

UNION [DISTINCT]의 경우는 내부적으로 TABLE이 비교적 작을때 UNION을 써보면 상당히 편해서 TABLE이 비교적 클때도 UNION을 자주 사용하게 되면 부하가 많이 발생한다.
따라서 중복여하가 필요없거나, 조회하고자 하는 데이터 자체가 중복될 일이 없을 경우는 UNION ALL을 사용하는 것이 부하를 덜 줄 수 있다. 

UNION ALL과 UNION 의 차이
UNION ALL은 중복을 제거하지 않고 그대로 합집합 연산을 해 결과를 보여주는 반면, UNION은  중복을 제거하여 결과를 보여줍니다.

UNION은 이미 SELECT된 결과를 가지고 UNION하기 때문에 SELECT되기 전의 테이블이나 레코드에 대한 정보는 알 수 없습니다. 그래서, 중복 여부의 판단은 SELECT된 튜플들에 속해있는 모든 컬럼의 값들 자체가 중복 체크의 기준이 되는 것입니다.


UNION 처리과정

1. 최종 UNION [ALL | DISTINCT] 결과에 적합한 임시 테이블(Temporary table)을 메모리 테이블로 생성
2. UNION 또는 UNION DISTINCT 의 경우, Temporary 테이블의 모든 컬럼으로 Unique Hash 인덱스 생성
3. 서브쿼리1 실행 후 결과를 Temporary 테이블에 복사
4. 서브쿼리2 실행 후 결과를 Temporary 테이블에 복사
5. 만약 3,4번 과정에서 Temporary 테이블이 특정 사이즈 이상으로 커지면 Temporary 테이블을 Disk Temporary 테이블로 변경  (이때 Unique Hash 인덱스는 Unique B-Tree 인덱스로 변경됨)
6. Temporary 테이블을 읽어서 Client에 결과 전송
7. Temporary 테이블 삭제


UNION 두 가지의 차이는 2번 과정 딱 하나입니다. 
중복 제거를 위해서 Temporary 테이블에 인덱스를 생성하는지 안하는지 입니다. 
별로 중요하지 않은 것 같지만, 이 인덱스로 인해서 3,4번 과정의 작업이 작지 않은 성능 차이가 만들어 내게 됩니다. 
실제 UNION을 실행하는 데이터의 건수에 따라서 다르겠지만, 1.5 ~ 4배 가량의 성능 차이로 UNION ALL이 빠르게 처리된다. 
만약 처리중 데이터의 크기가 작아서 5번 과정을 거치지 않는다면 메모리 Temporary 테이블에 Hash 인덱스를 사용하기 때문에 속도 차이가 아주 미세할 것입니다. 

하지만 데이터량이 커져서 5번 과정을 거치게 되면 Disk Temporary 테이블에 B-Tree 인덱스를 사용하기 때문에 큰 성능 차이를 보이게 됩니다. 
이 성능 차이는 UNION 하는 두 집합에 중복되는 레코드가 있든 없든 관계 없이 발생합니다. 
위에서 언급한 "중복"을 생각하면, UNION 하는 컬럼들의 수가 많아지고 레코드의 사이즈가 커질수록 두 작업 모두에게 불리하겠지만, UNION ALL보다는 UNION에 더 악영향이 클 것이다.


결론

UNION 이든지 UNION ALL이든지 사실 그리 좋은 SQL 작성은 아닙니다. 외부적으로는 하나의 SQL 구문을 실행하는 것처럼 보이지만, 내부적으로는 여러 개의 SELECT 구문을 실행하는 실행 계획으로 해석되기 때문입니다. 
따라서 테이블에 접근하는 횟수가 많아져서 I/O 비용이 크게 늘어납니다.
UNION이 필요하다는 것은 사실 두 엔터티(테이블)가 하나의 엔터티(테이블)로 통합이 되었어야 할 엔터티들이었는데, 
알 수 없는 이유로 분리 운영되었다는 경우입니다. 차라리 테이블 접근 I/O를 줄이기 위해서 테이블은 접근을 최소화로 하고 CASE문같은 조건으로 분기해주는것도 좋습니다.[물론 UNION을 처리하는게 좋은 경우도 있습니다.]

 

 

'IT' 카테고리의 다른 글

ANSI 표준  (0) 2022.06.30
[Oracle] 형 변환  (0) 2022.06.29
DBMS(DataBase Management System)란?  (0) 2022.06.28
SQL(Structured Query Language)이란?  (0) 2022.06.28
32bit와 64bit의 차이?  (0) 2020.06.16