🗄️ 데이터베이스

서브쿼리

Subquery

쿼리 안의 쿼리. 복잡한 조건 표현.

상세 설명

서브쿼리(Subquery)는 SQL 문 안에 포함된 또 다른 SELECT 문으로, 외부 쿼리가 사용할 결과를 제공합니다. 중첩 쿼리(Nested Query)라고도 부르며, WHERE, FROM, SELECT 절 등 다양한 위치에서 사용할 수 있습니다.

서브쿼리는 크게 스칼라 서브쿼리(단일 값 반환), 인라인 뷰(FROM 절에서 사용), 상관 서브쿼리(외부 쿼리 참조)로 구분됩니다. 복잡한 조건이나 계산이 필요할 때 유용하지만, 과도한 사용은 성능 저하를 유발할 수 있습니다.

일부 서브쿼리는 JOIN으로 변환하여 성능을 개선할 수 있습니다. 쿼리 옵티마이저가 자동으로 최적화하기도 하지만, 개발자가 의도적으로 변환하면 더 나은 실행 계획을 얻을 수 있습니다.

코드 예제

-- 스칼라 서브쿼리 (SELECT 절)
SELECT
    name,
    salary,
    (SELECT AVG(salary) FROM employees) as avg_salary
FROM employees;

-- WHERE 절 서브쿼리
SELECT name, department
FROM employees
WHERE department_id IN (
    SELECT id FROM departments
    WHERE location = 'Seoul'
);

-- 상관 서브쿼리 (Correlated Subquery)
SELECT e.name, e.salary
FROM employees e
WHERE e.salary > (
    SELECT AVG(salary)
    FROM employees
    WHERE department_id = e.department_id
);

-- EXISTS 서브쿼리
SELECT c.name
FROM customers c
WHERE EXISTS (
    SELECT 1 FROM orders o
    WHERE o.customer_id = c.id
    AND o.order_date > '2024-01-01'
);

-- 인라인 뷰 (FROM 절 서브쿼리)
SELECT dept_name, avg_salary
FROM (
    SELECT d.name as dept_name, AVG(e.salary) as avg_salary
    FROM departments d
    JOIN employees e ON d.id = e.department_id
    GROUP BY d.name
) dept_stats
WHERE avg_salary > 5000000;

실무 대화 예시

백엔드 개발자: 이 쿼리 너무 느린데, 서브쿼리가 여러 개 중첩되어 있어요.

DBA: 상관 서브쿼리네요. 외부 쿼리 행마다 서브쿼리가 실행되니까 느릴 수밖에요.

백엔드 개발자: JOIN으로 바꾸면 나아질까요?

DBA: 네, 대부분의 경우 JOIN이 더 효율적이에요. 옵티마이저가 실행 계획을 더 잘 세울 수 있거든요.

면접관: 서브쿼리와 JOIN의 차이점과 어떤 상황에서 서브쿼리를 사용하시나요?

지원자: 서브쿼리는 복잡한 조건이나 단일 값을 구할 때 가독성이 좋습니다. 하지만 상관 서브쿼리는 행마다 실행되어 성능 이슈가 있어서, 가능하면 JOIN으로 변환하는 게 좋습니다. EXISTS는 데이터 존재 여부만 확인할 때 효율적입니다.

면접관: 스칼라 서브쿼리의 주의점은요?

지원자: 스칼라 서브쿼리는 반드시 단일 행, 단일 열을 반환해야 합니다. 여러 행이 반환되면 에러가 발생해요.

시니어: 이 코드에서 서브쿼리가 세 번이나 같은 테이블을 조회하네요.

주니어: 네, 조건마다 필요해서요.

시니어: WITH 절(CTE)로 한 번 조회해서 재사용하거나, JOIN으로 리팩토링하면 성능이 훨씬 좋아질 거예요. 서브쿼리 중복은 피해야 합니다.

주의사항

관련 용어

더 배우기