SQL 서브쿼리를 빠르고 효율적으로 최적화하는 방법을 배워보세요! 서브쿼리 vs JOIN 비교, 실행 속도 개선, 성능 최적화 전략까지 실전 예제로 설명합니다. SQL 실행 속도를 10배 높이는 비법, 지금 확인하세요! 🚀
SQL 왕초보 가이드 - 3단계: 서브쿼리 최적화 🎯
📢 SQL 성능을 높이는 마법을 배워보자!
"데이터는 잘 불러오는데, 실행 시간이 너무 길어요!" 🤯
"부서별 최고 급여를 받는 직원을 찾고 싶은데, 어떻게 해야 하죠?" 🤔
이런 고민을 해결할 수 있도록, 오늘은 SQL 서브쿼리 최적화 기법을 배워볼 거예요! 🚀
1️⃣ 서브쿼리(Subquery)란?
서브쿼리는 "필요한 데이터를 찾기 위해 쿼리를 한 번 더 실행하는 방식"입니다. 📦🔍
🛠 서브쿼리 작동 방식
1️⃣ 서브쿼리가 먼저 실행되어 특정 데이터를 찾습니다.
2️⃣ 그 결과를 메인 쿼리가 다시 사용해서 최종 데이터를 검색합니다.
🚦 예제
SELECT employee_name, salary
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);
✅ 서브쿼리 실행 → MAX(salary)
를 찾아서 최고 급여를 반환.
✅ 메인 쿼리 실행 → 반환된 급여와 일치하는 직원 검색.
2️⃣ 부서별 최고 급여 직원 조회 (서브쿼리 활용)
✅ 목표:
- 부서별 최고 급여(
MAX(salary)
)를 받는 직원(employee_name
) 조회! 💰
📌 예제 테이블 스키마
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
employee_name VARCHAR(50),
department_id INT,
salary INT
);
CREATE TABLE departments (
department_id INT PRIMARY KEY,
department_name VARCHAR(50)
);
📌 예제 데이터
INSERT INTO employees VALUES
(1, 'Alice', 1, 7000), (2, 'Bob', 1, 6000),
(3, 'Charlie', 2, 8000), (4, 'David', 2, 7500);
INSERT INTO departments VALUES (1, 'HR'), (2, 'IT');
📌 기대 결과
department_name | employee_name | max_salary |
---|---|---|
HR | Alice | 7000 |
IT | Charlie | 8000 |
📌 SQL 정답
SELECT d.department_name, e.employee_name, e.salary AS max_salary
FROM employees e
JOIN departments d ON d.department_id = e.department_id
WHERE e.salary = (
SELECT MAX(salary)
FROM employees e2
WHERE e2.department_id = e.department_id
);
🚀 서브쿼리가 작동하는 방식
1️⃣ 서브쿼리 실행! 🏃♂️ → department_id
별 MAX(salary)
를 찾아줍니다.
2️⃣ 메인 쿼리 실행! 🎯 → 각 직원의 급여와 서브쿼리 결과(MAX(salary)
)를 비교해서 딱 맞는 사람만 출력!
🤔 근데… GROUP BY는 필요 없을까?
보통 MAX(salary)
같은 집계 함수를 쓰려면 GROUP BY
가 따라오는 게 자연스러운데, 이 쿼리는 왜 GROUP BY
없이도 돌아갈까요?
📌 이유는 간단해요!
- 서브쿼리는
department_id
별로 하나의 값을 반환하는 스칼라 값(단일 값)을 주기 때문이에요. - 만약
GROUP BY
를 추가하면 여러 개의 값이 나올 수도 있어서=
조건과 충돌할 가능성이 있습니다.
💡 정리하자면,
✔ 서브쿼리에서 특정 부서의 최고 급여 1개만 반환하니까 GROUP BY 필요 없음!
✔ GROUP BY를 쓰려면 메인 쿼리에서 서브쿼리 대신 JOIN을 활용하는 방법도 가능!
❓ GROUP BY를 추가하면 왜 문제가 될까?
처음 보면 "GROUP BY가 있으면 좋은 거 아닌가?" 싶을 수 있어요. 하지만 서브쿼리에서 GROUP BY
를 잘못 쓰면 메인 쿼리와 충돌할 수 있는 위험이 있어요! 😵
🚀 현재 서브쿼리 다시 보기!
WHERE e.salary = (
SELECT MAX(salary)
FROM employees e2
WHERE e2.department_id = e.department_id
)
✅ 이 서브쿼리는 각 부서(department_id
)에서 최고 급여(MAX(salary)
)를 딱 하나만 반환해요.
✅ 즉, WHERE e.salary = (서브쿼리 결과)
는 단 하나의 값(스칼라 값)과 비교하기 때문에 문제가 없죠!
❌ GROUP BY를 넣어버린다면... (문제 발생! ⚠️)
누군가 서브쿼리를 이렇게 수정했다고 해볼게요:
WHERE e.salary IN (
SELECT MAX(salary)
FROM employees e2
GROUP BY e2.department_id
)
🚨 이렇게 되면 문제가 생깁니다! 🚨
✔ GROUP BY e2.department_id
를 추가하면, 서브쿼리는 부서별 여러 개의 값을 반환하게 돼요.
✔ 하지만 WHERE e.salary = (서브쿼리 결과)
는 단 하나의 값과만 비교해야 하는데, 여러 개가 나오면 충돌이 발생해요!
📌 비유하자면?
- 정상 동작하는 기존 서브쿼리:
👉 "이 부서에서 제일 높은 급여가 얼마야?" → "7000!" (정확히 1개 값 반환!) ✅ GROUP BY
를 추가한 서브쿼리:
👉 "각 부서별 제일 높은 급여를 모두 가져와!" → "7000, 8000!" (여러 개 나옴!) ❌
🔹 이렇게 되면 WHERE e.salary = (여러 개의 값)
이 되면서, SQL이 어떤 값과 비교해야 할지 몰라서 오류가 발생할 가능성이 커집니다! 🚨
3️⃣ 서브쿼리의 단점? 속도가 느릴 수도 있어요! 🐢
이 방식, 간단하고 깔끔하긴 하지만… 큰 데이터셋에서 느릴 수도 있습니다! 🐌
왜냐하면? 각 직원마다 서브쿼리가 한 번씩 실행되기 때문이에요.
🔥 예를 들어 볼까요?
✔ 직원이 10명이면? 서브쿼리 10번 실행!
✔ 직원이 100만 명이면? 🏃♂️ 100만 번 실행! (헉😱)
📌 더 빠른 방법은? JOIN 활용! 🚀
4️⃣ CTE(WITH
)를 활용한 성능 개선! 🚀
📌 CTE(Common Table Expression)란?
WITH
키워드는 임시 테이블을 만들어 쿼리를 더 읽기 쉽게 정리하는 기능이에요.
일반적으로 서브쿼리를 대체하는 용도로 사용되며, 쿼리 실행이 끝나면 자동으로 사라지는 임시 테이블 역할을 합니다.
✅ CTE를 쓰면 좋은 점!
✔ 가독성 UP → 복잡한 서브쿼리를 깔끔하게 정리!
✔ 재사용 가능 → 한 번 정의한 CTE를 여러 번 활용할 수 있음
✔ 성능 최적화 → 일부 데이터베이스에서는 실행 계획을 더 효율적으로 짤 수 있음
🔥 CTE를 활용한 최적화된 SQL 예제!
WITH max_salaries AS (
SELECT department_id, MAX(salary) AS max_salary
FROM employees
GROUP BY department_id
)
SELECT d.department_name, e.employee_name, e.salary AS max_salary
FROM employees e
JOIN max_salaries ms ON e.department_id = ms.department_id AND e.salary = ms.max_salary
JOIN departments d ON d.department_id = e.department_id;
🔎 이렇게 하면 뭐가 좋아질까요?
1️⃣ 서브쿼리 대신 CTE 활용 → 쿼리 구조가 깔끔해짐!
- 기존 방식은
MAX(salary)
를 계산할 때마다 서브쿼리를 실행해야 했어요. - 하지만 CTE(
max_salaries
)를 사용하면 부서별 최대 급여를 먼저 구한 후 이를 활용해 메인 쿼리를 실행할 수 있어요.
2️⃣ 불필요한 연산 최소화 → 성능 개선!
max_salaries
CTE에서 부서별 최대 급여를 한 번만 계산하니까,
같은 연산을 반복하는 비효율적인 구조를 줄일 수 있어요.
3️⃣ 조인(Join) 최적화 → 실행 속도 향상!
employees
테이블과max_salaries
를department_id
및salary
로 조인해, 부서별 최고 연봉자만 추출!- 추가로
departments
테이블을 조인해서 부서 이름까지 함께 조회할 수 있어요.
💡 결론:
CTE(WITH
키워드)를 활용하면 SQL 쿼리가 더 깔끔하고, 성능도 좋아질 수 있다! 🚀
특히 반복 연산이 많은 서브쿼리를 최적화할 때 강력한 효과를 발휘하니, SQL 성능 튜닝할 때 꼭 활용해 보세요! 😎
🎯 서브쿼리 최적화 마무리!
오늘 배운 개념들 정리해볼까요? 🚀
✅ 서브쿼리
- SQL 안에서 또 다른 SQL을 실행하는 방식
- 결과를 가져와서 다시 필터링할 때 유용하지만 성능 저하 가능
✅ WITH를 활용한 최적화
- 서브쿼리보다 효율적인 방식으로 실행 속도 개선 가능!
📌 다음 가이드에서는 윈도우 함수를 활용한 성능 최적화 방법을 배워볼 거예요! 🚀
'SQL 왕초보 가이드' 카테고리의 다른 글
[SQL 03-2] SQL 윈도우 함수 완벽 정리! 🚀 초보도 쉽게 배우는 순위 & 누적 합계 계산법! (0) | 2025.02.10 |
---|---|
[SQL 02] GROUP BY & 집계 함수 완벽 가이드 | 데이터 분석을 위한 필수 SQL 📊 (0) | 2025.02.06 |
[SQL 01] JOIN 쉽게 이해하기 | 초보자를 위한 SQL 기초 강좌 📊 (0) | 2025.02.06 |