데이터베이스에서 복잡한 쿼리를 최적화하고 효율적으로 사용하기 위해 일반 테이블, TEMP TABLE(임시 테이블), WITH(CTE), VIEW(뷰) 를 활용할 수 있다.
각 방법마다 장단점이 다르기 때문에, 상황에 따라 적절한 방식을 선택하는 것이 중요하다!
✅ 일반 테이블이란?
일반 테이블은 데이터베이스에 영구적으로 저장되는 테이블이다.
모든 트랜잭션이 끝나도 데이터가 유지되며, INDEX를 사용할 수 있어 검색 성능이 좋다.
📌 일반 테이블이 필요한 이유
- 데이터를 영구적으로 저장해야 할 때
- INDEX를 활용해서 빠르게 조회해야 할 때
- 여러 트랜잭션에서 데이터를 공유해야 할 때
예를 들어, 상품 데이터처럼 지속적으로 유지되어야 하는 정보
CREATE TABLE products (
product_id INT PRIMARY KEY,
product_name VARCHAR(255),
price DECIMAL(10,2) );
→ 테이블을 생성하면, 해당 데이터는 데이터베이스에 영구적으로 저장됨
✅ TEMP TABLE(임시 테이블)이란?
TEMP TABLE(임시 테이블)은 특정 세션(Session)에서만 유지되는 테이블이다.
일반 테이블과 비슷하지만, 세션이 종료되면 자동으로 삭제된다.
📌 TEMP TABLE이 필요한 이유
- 서브쿼리 결과를 여러 번 사용할 때
- JOIN이 많거나 복잡한 연산을 최적화할 때
- 동일한 데이터를 여러 번 조회할 때 성능 개선 가능
예를 들어, 고객별 첫 구매일을 여러 번 JOIN해야 하는 경우
- WITH first_purchase AS (...) 사용 시 매번 데이터를 다시 계산해야 해서 비효율적
- TEMP TABLE에 저장하면 한 번만 계산하고 여러 번 재사용 가능
✅ VIEW(뷰)란?
VIEW(뷰)는 실제 데이터를 저장하지 않는 가상 테이블이다.
미리 정의된 쿼리를 저장해두고, 필요할 때마다 실행해서 최신 데이터를 가져올 수 있다.
📌 VIEW가 필요한 이유
- 복잡한 SQL을 단순화하고 쉽게 재사용할 때
- 사용자에게 보안적으로 제한된 데이터를 제공할 때 (예: 특정 컬럼만 보여주기)
- 매번 같은 쿼리를 반복해서 실행할 때
예를 들어, 주문 테이블과 고객 테이블을 매번 조인해서 분석하는 경우
- SELECT o.order_id, c.customer_name FROM orders o JOIN customers c ...
- VIEW를 생성하면 SELECT * FROM order_customer_view; 만 실행하면 됨!
✅ WITH(CTE, Common Table Expression)란?
WITH(CTE)는 SQL 실행 시 일시적으로 유지되는 가상의 테이블이다.
TEMP TABLE과 비슷하지만, TEMP TABLE처럼 데이터를 저장하지 않고 실행될 때만 유지된다.
📌 WITH(CTE)가 필요한 이유
- 한 번만 사용할 데이터를 간결하게 정리할 때
- 재귀 쿼리(Recursive Query)를 사용할 때
- 서브쿼리보다 가독성을 높이고 싶을 때
예를 들어, 회원별 총 주문 수를 구하는 쿼리가 여러 번 사용될 때
WITH order_counts AS (
SELECT customer_id, COUNT(order_id) AS total_orders
FROM orders GROUP BY customer_id
)
SELECT c.customer_name, oc.total_orders
FROM customers c JOIN order_counts oc
ON c.customer_id = oc.customer_id;
→ order_counts를 WITH(CTE)로 만들어 재사용 가능
✅ TEMP TABLE vs 일반 테이블 vs WITH(CTE) vs VIEW 비교 표
구분 | 일반 테이블 | TEMP TABLE (임시 테이블) |
WITH (CTE) | VIEW (뷰) |
데이터 저장 | ✅ 영구 저장 | ✅ 임시 저장 | ❌ 저장 안됨 | ❌ 저장 안됨 (가상 테이블) |
유지 기간 | ✅ 영구적 | ❌ 세션 종료 시 삭제 | ❌ 쿼리 실행 중에만 유지 | ✅ 영구적 |
속도 | ❌ 느릴 수 있음 (INDEX 없으면) | ✅ 빠름 (한 번 생성 후 재사용) | ⭕ 빠르지만 여러 번 실행 시 비효율적 | ❌ 실행할 때마다 원본 테이블 조회 |
INDEX 사용 | ✅ 가능 | ✅ 가능 | ❌ 불가능 | ❌ 불가능 (뷰 자체에는 INDEX 추가 불가) |
JOIN 사용 | ✅ 가능 | ✅ 가능 | ✅ 가능 | ✅ 가능하지만 성능 저하 가능 |
데이터 변경 가능 여부 | ✅ 가능 | ✅ 가능 | ❌ 불가능 | ❌ 불가능 (읽기 전용) |
사용 목적 | ✅ 영구적 데이터 저장 | ✅ 속도 개선 | ✅ 가독성 향상 | ✅ 복잡한 쿼리 재사용 |
✅ 언제 어떤 방식을 사용해야 할까?
📌 일반 테이블이 더 좋은 경우
- 데이터를 영구적으로 저장해야 할 때
- INDEX를 활용해서 빠르게 조회해야 할 때
- 여러 트랜잭션에서 데이터를 공유해야 할 때
📌 TEMP TABLE이 더 좋은 경우
- JOIN이 많거나, 반복적으로 실행되는 쿼리를 최적화할 때
- 서브쿼리 결과를 여러 번 재사용해야 할 때
- 대량 데이터를 처리할 때 속도를 개선하고 싶을 때
📌 WITH(CTE)가 더 좋은 경우
- 한 번만 사용할 데이터를 처리할 때
- 쿼리를 단순화하고 가독성을 높이고 싶을 때
- 재귀 쿼리(Recursive Query)를 사용할 때
📌 VIEW(뷰)가 더 좋은 경우
- 복잡한 SQL 쿼리를 단순하게 만들어서 재사용하고 싶을 때
- 원본 테이블의 데이터를 변형하지 않고, 최신 데이터를 조회해야 할 때
🔥 최종 정리
✔ TEMP TABLE → "임시 저장소", 일반 테이블 → "영구 저장소"
✔ WITH(CTE) → "실행할 때만 유지", VIEW → "미리 정의된 가상 테이블"
✔ 속도가 중요한 경우 TEMP TABLE을, 가독성이 중요한 경우 VIEW를 사용하면 좋다!
'학습 > SQL' 카테고리의 다른 글
[solvesql] SQL 풀어보기 - 유량(Flow)와 저량(Stock) (누적합구하기) (0) | 2025.03.11 |
---|---|
[solvesql] SQL 풀어보기 - 폐쇄할 따릉이 정류소 찾기 2 (0) | 2025.03.10 |
[solvesql] SQL 풀어보기 - 레스토랑 요일 별 구매금액 Top 3 영수증 (0) | 2025.03.09 |
[solvesql] SQL 풀어보기 - 가구 판매의 비중이 높았던 날 찾기 (0) | 2025.03.08 |
[프로그래머스]SQL 학습 - 상품을 구매한 회원 비율 구하기 (0) | 2025.03.07 |