서브쿼리(Subquery)란 sql내에 다른 sql이 포함되어있는 포함되어있는 쿼리를 의미합니다.
스칼라 서브쿼리(Scalar Subquery)는 주로 SELECT 절이나 다른 쿼리의 일부로서 단일 값을 반환하는 서브쿼리를 말합니다. 스칼라 서브쿼리는 반드시 단일 값(하나의 행과 하나의 열)을 반환해야 하며, 이를 통해 주 쿼리에서 계산이나 조건 비교 등의 작업에 사용할 수 있습니다.
WHERE 절이나 HAVING 절에 사용되는 서브쿼리는 서브쿼리지만, 일반적으로 “스칼라 서브쿼리”라고 지칭하지 않습니다. 보통 WHERE 절에 사용되는 서브쿼리는 존재 여부를 확인하는 서브쿼리(Existential Subquery) 또는 다중 행 서브쿼리(Multi-row Subquery)로 불릴 수 있습니다.
스칼라 서브쿼리의 사용 예
1. SELECT 절에서 사용
스칼라 서브쿼리는 주로 SELECT 절에서 하나의 값을 계산하거나 가져오는 데 사용됩니다. 예를 들어, 각 직원의 부서 평균 급여를 가져오는 경우
SELECT employee_id, first_name, last_name, salary,
(SELECT AVG(salary) FROM employees WHERE department_id = e.department_id) AS avg_department_salary
FROM employees e;
위 쿼리의 수행 순서는 메인 쿼리 -> 서브 쿼리 순으로 동작합니다.
서브쿼리는 결과 건수만큼 반복 수행되기 때문에 조회되는 데이터의 갯수가 적다면 크게 문제될 것은 없지만,
조회 되는 데이터의 갯수가 많아지면 많아질 수록 성능이 현저히 떨어지는 모습을 볼 수 있습니다.
또한 스칼라 서브쿼리 사용시 서브쿼리의 결과값이 같은 경우가 많거나, 매번 동일한 결과값을 반환한다면, 스칼라 서브쿼리의 캐싱 효과를 통해 성능을 높일 수 있으나, 서브쿼리에서 사용되는 조건의 종류가 많아지거나 혹은 조건 데이터가 지속적으로 바뀔경우 캐싱의 효율성이 떨어지기 때문에 이전보다 성능이 떨어질 수 있습니다.
서브쿼리는 매번 변하는 결과값을 모든행마다 조회해야한다면 가능하다면 from 절에서 join 하는 방식으로 수정해야 한다.
SELECT e.employee_id, e.first_name, e.last_name, e.salary, d.avg_department_salary
FROM employees e
LEFT JOIN (
SELECT department_id, AVG(salary) AS avg_department_salary
FROM employees
GROUP BY department_id
) d ON e.department_id = d.department_id;