본문 바로가기

개발

[SQL] SubQuery, 서브쿼리

서브쿼리란?

서브쿼리(subquery)란 다른 쿼리 내부에 포함되어 있는 Select문을 의미한다.

서브쿼리는 ()로 감싸져서 포함된다.

select * 
from main_table
where target_id in (
	select id
	from sub_table
	where id < 10
);

서브쿼리가 먼저 실행되고, 메인 쿼리가 실행된다.

서브쿼리의 종류

중첩 서브쿼리

where 문에 사용하는 서브쿼리

// 상수
select name, height
from userTable
where height > 177

// 조건 값을 select로 특정할 때, 단 결과 값이 1개여야함
select name, height
from userTable
where height > (select height from userTable where name in ('홍길동'));

// 조건에 값이 여러개, any 사용
select name, height 
from userTable
where height = any(select height from userTable where addr in ('경상도'));

// all은 도출된 모든 조건값에 만족할때
select *
from city
where population > all(select population from city where district = '전라도');

인라인 뷰(Inline View)

from 문에 사용하는 서브쿼리

서브쿼리가 from 절에 사용될 경우에는 꼭 alias를 지정해줘야한다.

select sub.name, sub.age
from (
	select *
	from student as s
	where s.addr = '서울'
) sub;

 

스칼라 서브쿼리(Scalar Subquery)

select 문에 나타나는 서브쿼리

하나의 레코드만 리턴이 가능하다.

일치하는 데이터가 없으면 null 값을 리턴할 수 있다.

select 
	name, 
	(select depart_name from departments where id = employees.department_id) as department_name,
	salary
from
	employees;

JOIN 과의 비교

Join 은 여러개의 쿼리를 필요로하진 않는다. 서브쿼리는 여러개의 쿼리를 사용한다.

Join은 2개 혹은 그 이상의 테이블을 연결하고, 연결한 테이블로부터 필요한 열을 조회할 수 있도록 한다.

서브쿼리와 조인 모두 여러개의 테이블로부터 데이터를 추출하기 위한 복잡한 쿼리문에 사용될 순 있지만, 접근 방식은 다르다. 상황에 따라 둘 다 가능할 때가 있고, 둘 중 하나만이 유일한 해결 방법일 수도 있다.

서브쿼리는 가독성이 좋지만 조인에 비해 성능이 매우 좋지 않다.

따라서 JOIN으로 대체할 수 있다면 대체하는 것이 좋다.

// 서브쿼리
SELECT name, cost
FROM product
WHERE id =
( 
  SELECT product_id
  FROM sale
  WHERE price = 2000
  AND product_id = product.id 
);

// join
SELECT p.name, p.cost
FROM product AS p
JOIN sale AS s -- inner join
ON p.id = s.product_id
WHERE s.price = 2000;

서브쿼리의 장단점

서브쿼리의 장점

  • 편하다. 다양하게 활용 할 수 있다.
  • 쿼리를 구조화 시키므로 쿼리의 각 부분을 명확히 구분할 수 있게 한다.
  • 복잡한 JOIN 이나 UNION과 같은 동작을 수행할 수 있는 또 다른 방법을 제공한다.
  • 복잡한 JOIN 이나 UNION 보다 좀 더 읽기 편하다.

서브쿼리의 단점

  • 성능이 나빠질 수 있다.
    • 불필요한 join 연산을 하진 않는지, 불필요한 테이블 접근을 하진 않는지.
  • 쿼리가 복잡해지면 가독성이 좋지 않다.
  • 연산 비용 추가
    • 서브쿼리는 테이블과 같은 형태의 결과 값을 만들어 내지만, 실제 데이터를 저장하지는 않는다. 따라서 쿼리가 실행될때마다 같은 동작을 반복해야한다. 서브쿼리에 접근할 때마다 select 구문을 실행해야한다.
    • → 연산 비용을 줄이기 위해서 테이블에 접근하는 횟수를 줄이면 된다.
  • 데이터 I/O 비용 발생
  • 최적화를 받을 수 없음
    • 서브쿼리는 일반 테이블과 다르게 데이터를 설명하는 메타 데이터를 가지고 있지 않는다. 따라서 옵티마이저가 최적화를 해줄 수 없을 수 있다.

결론

서브쿼리는 장단점이 존재하나, 절대적이지 않다. 상황에 맞게 잘 활용하는 능력이 필요하다.

참고사이트

[SQL] 성능 관점에서의 서브쿼리(Subquery)

[MYSQL] 📚 JOIN과 서브쿼리 차이 및 변환 💯 정리

'개발' 카테고리의 다른 글

[Java] Thread-Safe, 스레드 안전  (0) 2024.06.01
[Java] Java의 메모리 영역, 컴파일 방식  (0) 2024.06.01
[React] DOM, Virtual DOM  (0) 2024.06.01
인증/인가 (feat. Cookie, Session)  (0) 2024.05.26
ESM과 CommonJS의 차이  (0) 2024.05.26