서브쿼리란?
서브쿼리(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 비용 발생
- 최적화를 받을 수 없음
- 서브쿼리는 일반 테이블과 다르게 데이터를 설명하는 메타 데이터를 가지고 있지 않는다. 따라서 옵티마이저가 최적화를 해줄 수 없을 수 있다.
결론
서브쿼리는 장단점이 존재하나, 절대적이지 않다. 상황에 맞게 잘 활용하는 능력이 필요하다.
참고사이트
'개발' 카테고리의 다른 글
[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 |