SQLD 시험 문제: 서브쿼리(Subquery)
SQLD 시험의 핵심 서브쿼리 완벽 정복하기
데이터베이스 자격증인 SQLD를 준비하는 수험생들에게 가장 높은 벽으로 느껴지는 개념 중 하나가 바로 서브쿼리입니다. 서브쿼리는 하나의 SQL 문장 안에 포함된 또 다른 SQL 문장을 의미하는데, 단순히 데이터를 조회하는 것을 넘어 복잡한 비즈니스 로직을 구현할 때 필수적인 도구입니다. 서브쿼리를 자유자재로 다룰 수 있다는 것은 데이터베이스의 데이터를 입체적으로 분석할 수 있다는 뜻이며, 실무에서도 매우 강력한 무기가 됩니다.
서브쿼리의 기본 개념과 중요성
서브쿼리는 메인 쿼리의 결과를 결정하거나, 메인 쿼리에 조건을 부여하기 위해 사용됩니다. 예를 들어 ‘전체 평균 급여보다 높은 급여를 받는 직원’을 찾는다고 가정해 봅시다. 이 경우 전체 평균 급여를 구하는 쿼리가 먼저 수행되어야 하고, 그 값을 바탕으로 메인 쿼리가 다시 전체 직원을 조회해야 합니다. 이때 평균 급여를 구하는 쿼리가 바로 서브쿼리가 됩니다.
서브쿼리가 중요한 이유는 SQL을 절차적인 프로그래밍 언어처럼 유연하게 사용할 수 있게 해주기 때문입니다. 복잡한 데이터를 여러 단계로 나누어 처리함으로써 가독성을 높이고, 반복되는 쿼리를 줄여 유지보수 효율을 극대화할 수 있습니다.
서브쿼리의 위치에 따른 분류와 특징
서브쿼리는 작성되는 위치에 따라 이름과 역할이 달라집니다. SQLD 시험에서는 이 위치를 정확히 구분하는 것이 고득점의 열쇠입니다.
- SELECT 절에 위치하는 스칼라 서브쿼리: 하나의 행과 하나의 컬럼만을 반환하는 서브쿼리입니다. 마치 함수처럼 작동하며, 메인 쿼리의 각 행마다 실행되는 특성이 있어 조인보다 효율적일 때가 많습니다.
- FROM 절에 위치하는 인라인 뷰: 서브쿼리의 결과가 마치 테이블처럼 사용됩니다. 복잡한 집계 데이터를 미리 계산해두고, 그 결과 위에서 다시 필터링을 수행할 때 매우 유용합니다.
- WHERE 절에 위치하는 중첩 서브쿼리: 가장 흔하게 사용되는 유형으로, 메인 쿼리의 조건절에서 필터링 역할을 합니다. 반환되는 결과의 개수에 따라 단일 행, 다중 행 서브쿼리로 세분화됩니다.
서브쿼리 실행 순서와 성능의 이해
많은 입문자가 오해하는 부분 중 하나가 서브쿼리는 항상 메인 쿼리보다 먼저 실행된다는 생각입니다. 하지만 이는 DBMS의 최적화 엔진에 따라 달라질 수 있습니다. 일반적으로는 서브쿼리가 먼저 실행되어 결과를 메인 쿼리에 전달하지만, 최신 옵티마이저들은 성능을 최적화하기 위해 실행 순서를 내부적으로 변경하거나 조인 방식으로 변환하기도 합니다.
성능 관점에서 볼 때, 서브쿼리를 남발하면 시스템 부하가 커질 수 있습니다. 특히 상관 서브쿼리(메인 쿼리의 컬럼을 서브쿼리 내부에서 참조하는 형태)는 메인 쿼리의 각 행마다 서브쿼리가 반복 실행되므로, 데이터 양이 많아질수록 성능이 급격히 저하될 위험이 있습니다. 이러한 경우 가급적 조인(JOIN)으로 변경하여 작성하는 것이 비용 효율적입니다.
서브쿼리 사용 시 반드시 알아야 할 제약 사항
SQLD 시험에서 자주 등장하는 제약 사항들을 명확히 숙지해야 합니다. 서브쿼리를 사용할 때는 다음 규칙을 준수해야 문법 오류를 피할 수 있습니다.
- 서브쿼리는 괄호로 감싸야 합니다.
- 서브쿼리 내부에는 ORDER BY 절을 사용할 수 없습니다(일부 예외적인 상황 제외). 정렬은 결과에 영향을 미치지 않으며, 메인 쿼리에서 정렬을 수행해야 합니다.
- 다중 행 서브쿼리(결과가 여러 개)를 사용할 때는 반드시 IN, ANY, ALL, EXISTS와 같은 다중 행 연산자를 사용해야 합니다. 단일 행 연산자(=, <, > 등)를 사용하면 런타임 에러가 발생합니다.
자주 묻는 질문과 전문가의 조언
Q: 서브쿼리와 조인 중 어떤 것이 더 좋은가요?
A: 정답은 없습니다. 과거에는 조인이 항상 빠르다고 알려졌지만, 현재는 옵티마이저가 매우 지능적이어서 두 방식의 성능 차이가 크지 않은 경우가 많습니다. 다만, 데이터의 관계가 1대 다수이거나 복잡한 집계가 필요할 때는 인라인 뷰를 활용한 서브쿼리가 가독성 면에서 훨씬 우수합니다.
Q: EXISTS 연산자는 왜 사용하나요?
A: EXISTS는 데이터의 존재 여부만을 확인합니다. 특정 행이 존재하는지 확인하는 즉시 검색을 멈추기 때문에, 데이터의 값이 필요 없고 단순히 존재 여부만 따질 때 성능 면에서 매우 유리합니다.
전문가의 팁: 실무에서는 가독성을 위해 서브쿼리를 사용하되, 성능 문제가 발생하면 해당 서브쿼리를 조인으로 변환하는 연습을 반복해보세요. SQLD 시험에서도 ‘어떤 서브쿼리가 조인으로 변환 가능한가’를 묻는 문제가 자주 출제되므로, 두 개념을 연결해서 공부하는 것이 중요합니다.
실생활 활용 사례를 통한 이해
예를 들어 쇼핑몰 데이터를 관리한다고 가정해 보겠습니다. ‘지난달 주문을 한 번도 하지 않은 고객 명단’을 추출해야 한다면 어떻게 할까요? 이때 서브쿼리가 빛을 발합니다.
메인 쿼리에서는 ‘전체 고객’을 조회하고, WHERE 절에 ‘NOT EXISTS’ 서브쿼리를 넣어 ‘주문 테이블에 해당 고객의 ID가 존재하는지’를 확인합니다. 이렇게 하면 복잡한 외부 조인을 사용하지 않고도 논리적으로 명확한 쿼리를 작성할 수 있습니다.
또 다른 예로, 부서별로 가장 높은 급여를 받는 사람을 찾을 때는 인라인 뷰를 사용합니다. 부서별 최대 급여를 서브쿼리로 구하고, 이를 원본 테이블과 조인하면 간단하게 해결됩니다. 이처럼 서브쿼리는 비즈니스 요구사항을 SQL로 번역하는 핵심 언어와 같습니다.
흔한 오해와 사실 관계 확인
많은 학습자가 ‘서브쿼리는 느리다’는 편견을 가지고 있습니다. 하지만 이는 서브쿼리 자체의 문제라기보다는 작성 방식의 문제입니다. 상관 서브쿼리를 대량의 데이터에 적용하거나, 불필요하게 중첩된 서브쿼리를 사용하는 경우에만 느려집니다. 제대로 작성된 서브쿼리는 오히려 복잡한 조인보다 실행 계획이 단순하고 가독성이 좋아 실무에서 선호되기도 합니다.
또한 ‘서브쿼리는 FROM 절에만 쓸 수 있다’는 오해도 있습니다. 서브쿼리는 SELECT, FROM, WHERE, HAVING, ORDER BY 등 거의 모든 절에서 사용 가능하며, 심지어 INSERT나 UPDATE 문장에서도 활용할 수 있습니다.
비용 효율적인 활용을 위한 전략
데이터베이스의 자원(CPU, 메모리)을 아끼면서 효율적인 쿼리를 작성하려면 다음 전략을 기억하세요.
- 불필요한 중복 제거: 같은 결과를 반환하는 서브쿼리가 여러 번 호출된다면, WITH 구문을 사용하여 임시 결과 집합을 정의하고 재사용하는 것이 좋습니다.
- 필요한 컬럼만 조회: 서브쿼리 내부에서 SELECT *를 사용하는 것은 금물입니다. 필요한 컬럼만 정확히 지정해야 데이터 처리 속도가 빨라집니다.
- 인덱스 활용: 서브쿼리 조건절에 사용된 컬럼에 인덱스가 걸려 있는지 확인하세요. 인덱스가 없다면 데이터베이스는 모든 행을 스캔해야 하므로 성능이 저하됩니다.
SQLD 시험은 단순히 문법을 암기하는 시험이 아닙니다. 서브쿼리가 어떤 상황에서 어떤 연산자와 함께 사용되어야 하는지, 그리고 그것이 데이터베이스 성능에 어떤 영향을 미치는지를 이해하는 것이 합격의 지름길입니다. 서브쿼리의 구조를 파악하고, 다양한 예제를 직접 타이핑해보며 실행 계획을 확인하는 습관을 들인다면, 시험은 물론 실무에서도 데이터 전문가로서의 역량을 충분히 발휘할 수 있을 것입니다.
ace


댓글 0
첫 댓글을 남겨보세요.