데이터 베이스/데이터베이스 기본

Ch03. 서브쿼리 - 서브쿼리 VS Join

webmaster 2026. 5. 30. 19:16

지금까지 "JOIN"과 서브 쿼리라는두 가지 강력한 기술을 배웠다. 그러면서 아마도 이런 의문이 들었을 것이다. "? 어떤 문제는 가지 방법으로 모두 있네?" 맞다. 실제로 많은 문제는 "JOIN"으로도, 서브쿼리로도 해결할 있다. 그렇다면 우리는 무엇을 선택해야 할까? 성능과 가독성 측면에서 둘은 어떤 차이가 있을까?

 

 

문제 상황: "서울에 거주하는 모든 고객들의 주문 목록을 조회해라."

 

해결 방법 1. 서브 쿼리 사용

서브쿼리를 이용한 접근법은 우리의 사고 흐름과 매우 유사하다.

  • 먼저, 서울에 사는 고객들의 "user_id" 목록을 찾는다 (users 테이블).
  • 그다음, "user_id" 목록에 포함된 "order_id"를 가진 주문들을 찾는다 (orders 테이블).
select *
from orders o
where o.user_id in (
					select user_id 
					from users 
					where address like '서울%'
                    );

 

쿼리 결과

  • 이 쿼리는 읽기가 매우 쉽다. "users 테이블에서 address가 '서울'인 고객 "user_id" 목록 안에(IN), "user_id"가 포함된 "orders"를 찾아줘"라고 말하는 것과 같다.

해결 방법 2. Join 사용

"JOIN" 이용한 접근법은 필요한 테이블들을 일단 모두 연결한 , 원하는 조건을 필터링하는 방식이다.

select 
	o.order_id,
    o.user_id,
    o.product_id,
    o.order_date
from orders o
join users u on o.user_id = u.user_id
where u.address like '서울%';

쿼리 결과

  • "주문(orders)과 고객(users) 테이블을 "user_id"로 연결한 다음, 그중에서 고객 주소가 "서울"인 데이터만 걸러줘"와 동일하다
  • 결과는 당연히 서브쿼리를 사용했을 때와 동일하다.

성능 vs 가독성: 실무 가이드

성능 (Performance): 일반적으로, 데이터베이스는 "JOIN" 서브쿼리보다 성능이 좋거나 최소한 동일한 경우가 많다.

 

그럴까? 비밀은 데이터베이스의 "두뇌" 역할을 하는 쿼리 옵티마이저(Query Optimizer) 있다.

  • "JOIN" 구문은 옵티마이저에게 더 많은 정보를 제공한다. "A와 B 테이블을 특정 조건으로 연결해야 한다"는 전체 그림을 미리 보여주기 때문에, 옵티마이저는 인덱스를 어떻게 활용하고 어떤 테이블을 먼저 읽을지 가장 효율적인 실행 계획을 선택할 있는 넓은 선택지를 갖는다.
  • 반면, 서브쿼리는 (특히 과거의 데이터베이스에서는) 단계적으로 실행되는 경우가 많았다. 서브쿼리를 먼저 실행해서 나온 결과를 메모리에 담아두고, 그다음 메인쿼리가 결과를 참조하는 방식으로 동작하여 비효율을 야기 있었다.

하지만! 요즘 데이터베이스의 옵티마이저는 매우 똑똑해져서, 우리가 작성한 예제처럼 간단한 "IN" 서브쿼리는 내부적으로 최적의 "JOIN" 구문으로 자동 변환해서 실행하는 경우가 많다. 따라서 예제의 쿼리는 사실상 동일한 성능을 낼 확률이 높다. 참고로 이런 최적화는 항상 가능한 것은 아니기 때문에 쿼리 실행 계획 등을 확인하는 것이 좋다.

 

가독성 (Readability) : 가독성은 주관적인 영역이지만, 쿼리의 유지보수 측면에서 성능만큼이나 중요하다.

  • 서브쿼리는 쿼리의 논리적 단계를 명확하게 구분해 주어, 복잡한 로직을 더 이해하기 쉽게 만들어주는 경우가 많다.
  • "JOIN" 쿼리에 필요한 모든 데이터 소스를 한눈에 보여주고, 여러 테이블의 컬럼을 함께 조회해야 때는 구조적으로 깔끔하다.

 

최종 결론: 언제 무엇을 써야 할까?

정답은 없다. 하지만 실무에서 적용할 있는 가이드라인은 다음과 같다.

 

  1. "JOIN"을 우선적으로 고려하라.
    • 일반적인 성능 우위와 범용성을 고려할 , 문제를 해결할 방법을 "JOIN"에서 먼저 찾아보는 것이 좋은 출발점이.
  2. "JOIN"으로 표현하기 너무 복잡하거나, 서브쿼리의 가독성이 훨씬 좋다면 서브쿼리를 사용하라.
    • 성능이 아주 중요한 쿼리가 아니라면, 동료가 이해하기 쉬운 코드를 작성하는 것이 장기적으로 가치 있을 . 특히 인라인 뷰를 사용해야만 깔끔하게 풀리는 문제는 서브쿼리가 정답이다.
  3. "EXISTS"를 활용하라.
    • "IN" 서브쿼리의 대안으로, "EXISTS"라는 서브쿼리 연산자도 있다. "EXISTS" 서브쿼리의 결괏값이 존재하는지 여부만 체크하기 때문에, 특정 상황에서 효율적으로 동작하기도 한다.
  4. 성능이 의심될 때는 반드시 측정하라.
    • 가장 중요한 원칙이다. 추측하지 말고, "EXPLAIN"과 같은 도구를 사용해 데이터베이스가 어떻게 쿼리를 실행하는 계획을 분석하고, 실제 실행 시간을 측정하여 나은 방법을 선택해야 한다.

 

"JOIN" 서브쿼리는 대립하는 기술이 아니라, 데이터라는 재료를 요리하는 가지 필수 도구다. 각각의 장단점을 이해하고 상황에 맞게 꺼내 사용할 있어야 한다.

'데이터 베이스 > 데이터베이스 기본' 카테고리의 다른 글

Ch05. CASE문 - 그룹핑  (0) 2026.06.02
Ch05. CASE문 - CASE문 기본  (0) 2026.06.02
Ch04. UNION - UNION 정렬  (0) 2026.05.31
Ch04. UNION - UNION ALL  (0) 2026.05.31
Ch04. UNION - UNION  (0) 2026.05.31