"마케팅팀에서 두 종류의 고객에게 이벤트 안내 메일을 보내려고 한다. 첫 번째 그룹은 '전자기기' 카테고리의 상품을 구매한 이력이 있는 고객이고, 두 번째 그룹은 '서울'에 거주하는 고객이다. 두 그룹의 명단을 합쳐서 전체 발송 목록을 만들고 싶다."
'서울'에 살면서 '전자기기'를 구매한 고객은 두 그룹에 모두 속하게 되는데, 이 고객을 최종 목록에 한 번만 포함해야 할까? 아니면 중복을 허용해도 될까?? -> 정답은 "비즈니스 요구사항에 따라 다르다" 이다. 하지만 이 선택에 따라 우리는 "UNION"과 "UNION ALL" 중 무엇을 쓸 지결정해야 한다.
UNION과 UNION ALL의 차이
"UNION"과 "UNION ALL"의 유일한 차이점은 "중복 처리" 여부다.
- "UNION": 두 결과 집합을 합친 후, 중복된 행을 제거한다.
- "UNION ALL": 중복 제거 과정 없이, 두 결과 집합을 그대로 모두 합친다.
UNION 사용 시 (중복 제거)
-- 전자기기 구매 고객
select u.name, u.email
from users u
join orders o on u.user_id = o.user_id
join products p on o.product_id = p.product_id
where p.category = '전자기기'
union
-- 서울 거주 고객
select name, email
from users
where address like '서울%';

- 전자기기 구매 고객: 션, 마리 퀴리, 네이트, 네이트(중복), 이순신
- 서울 거주 고객: 션, 세종대왕, 마리 퀴리
- 중복 고객: 션, 네이트(중복), 마리 퀴리
"UNION"은 이 중복을 제거하고 고유한 목록만 보여준다.
UNION ALL 사용 시 (중복 허용)
-- 전자기기 구매 고객
select u.name, u.email
from users u
join orders o on u.user_id = o.user_id
join products p on o.product_id = p.product_id
where p.category = '전자기기'
union all
-- 서울 거주 고객
select name, email
from users
where address like '서울%';

- "UNION ALL"은 각 "SELECT"문의 결과를 그대로 모두 이어 붙인다.
- "전자기기" 구매 내역은 총 5건(네이트 2건 포함)이고, "서울" 거주 고객은 3명이므로 총 8개의 행이 반환된다.
- 결과를 보면 "션", "네이트", "마리 퀴리"가 중복되어 나타나는 것을 확인할 수 있다.
실무 가이드: 성능이 핵심이다
"UNION ALL"이 "UNION"보다 훨씬 빠르다.
- UNION
- 두 결과를 합친 뒤, 중복을 제거하기 위해 데이터베이스는 보이지 않는 곳에서 추가 작업을 해야 한다.
- 보통 전체 결과를 정렬(Sort)한 다음, 서로 인접한 행들을 비교하여 중복을 찾아내는 과정을 거친다. 데이터의 양이 수십만, 수백만 건이라면 이 정렬과 비교 작업은 엄청난 비용과 시간을 소모한다.
- UNION ALL
- 추가 작업이 전혀 없다. 그냥 첫 번째 "SELECT" 결과 아래에 두 번째 "SELECT" 결과를 가져다 붙이기만 하면 된다.
실무에서의 가이드
- 중복을 제거해야만 하는 명확한 요구사항이 있을 때만 "UNION"을 사용한다.
- 예: 고유한 이메일 주소 목록, 고유한 고객 ID 목록 등
- 그 외의 모든 경우에는 "UNION ALL"을 우선적으로 사용한다.
- 두 결과 집합에 중복이 발생할 수 없다는 것을 명확히 아는 경우.
- 중복이 발생해도 비즈니스 로직상 상관없는 경우.
"중복을 제거할 필요가 없다면, 항상 "UNION ALL"을 사용하자". 불필요한 "UNION" 사용은 쿼리를 느리게 만드는 주범이 될 수 있다.
'데이터 베이스 > 데이터베이스 기본' 카테고리의 다른 글
| Ch05. CASE문 - 그룹핑 (0) | 2026.06.02 |
|---|---|
| Ch05. CASE문 - CASE문 기본 (0) | 2026.06.02 |
| Ch04. UNION - UNION 정렬 (0) | 2026.05.31 |
| Ch04. UNION - UNION (0) | 2026.05.31 |
| Ch03. 서브쿼리 - 서브쿼리 VS Join (0) | 2026.05.30 |