
데이터베이스 설계자에게 있어 "가독성"과 "성능"은 언제나 트레이드오프(Trade-off) 관계에 있습니다. MySQL 8.0 이후 우리는 복잡한 쿼리를 처리하기 위해 VIEW와 WITH 절(CTE)이라는 비슷한 두개의 방식을 알수 있습니다.
이 두가지의 기능은 단순히 "문법이 다르다"는 간단한 수준을 넘어, 이번 포스팅에서는 메모리 구조, 옵티마이저의 처리 방식, 그리고 실무 아키텍처 관점에서 두 기능을 비교해 보겠습니다.
1. 근본적인 아키텍처의 차이
VIEW: 영구적인 논리 레이어 (Permanent Logical Layer)
VIEW는 데이터베이스 카탈로그에 저장되는 객체(Object)입니다.
- 컴파일 시점: VIEW를 생성할 때 MySQL은 구문을 분석하고 권한을 체크합니다.
- 생명 주기: DROP VIEW를 하기 전까지는 데이터베이스에 존재합니다.
- 동작 방식: 쿼리 실행 시점에 원본 테이블과 결합(Merge)되어 실행 계획이 수립됩니다.
WITH 절(CTE): 일시적인 실행 컨텍스트 (Transient Execution Context)
CTE는 쿼리가 실행되는 동안에만 살아있는 메모리 상의 이름표입니다.
- 컴파일 시점: 본 쿼리가 파싱될 때 함께 처리됩니다.
- 생명 주기: 쿼리 결과가 반환되는 즉시 메모리에서 해제됩니다.
- 동작 방식: 필요에 따라 임시 테이블로 구체화(Materialization)되거나 내부적으로 인라인화(Inlining)됩니다.
2. 성능 최적화: 옵티마이저의 선택
성능 면에서 두 기능은 MySQL 옵티마이저에 의해 다르게 취급됩니다.
① VIEW의 Merge 알고리즘
VIEW를 호출하면 옵티마이저는 VIEW의 정의를 본 쿼리에 병합(Merge)하려고 시도합니다. 예를 들어 VIEW에 WHERE 조건이 있고 본 쿼리에도 WHERE 조건이 있다면, 이를 합쳐서 원본 테이블의 인덱스를 최대한 타게 만듭니다. 이는 성능 면에서 매우 유리합니다.
② CTE의 Materialization (구체화)
CTE는 동일한 이름을 쿼리 내에서 여러 번 참조할 때 강력합니다. MySQL은 CTE 결과를 한 번 계산해서 임시 테이블(Internal Temporary Table)에 담아두고 재사용합니다.
- 장점: 복잡한 계산을 한 번만 수행함.
- 단점: 임시 테이블에는 원본 테이블의 인덱스가 없습니다. 데이터가 수십만 건을 넘어가면 이 임시 테이블을 다시 풀 스캔(Full Scan)해야 하므로 성능이 급격히 저하될 수 있습니다.
3. 실무 시나리오별 심층 비교 분석
시나리오 1: 데이터 거버넌스와 보안 (Security)
- 승자: VIEW
- 분석: 특정 부서에 사원들의 '급여'를 제외한 정보만 보여줘야 한다면, WITH 절은 대안이 될 수 없습니다. WITH 절은 사용자가 원본 테이블에 접근 권한이 있어야만 실행 가능하기 때문입니다. VIEW는 원본 테이블 권한은 없어도 VIEW 조회 권한만 따로 부여할 수 있는 보안 샌드박스 역할을 수행합니다.
시나리오 2: 복잡한 통계 및 리포팅 (Reporting)
- 승자: WITH 절 (CTE)
- 분석: 연말 결산을 위해 1단계(월별 집계), 2단계(분기별 비교), 3단계(전년 대비 증감)를 거치는 쿼리를 짠다고 가정해 봅시다. 이를 VIEW로 만들면 관리해야 할 VIEW가 3개나 늘어납니다. WITH 절은 한 화면에서 로직의 흐름을 단계별로 보여주므로 유지보수성이 압도적입니다.
시나리오 3: 계층형 데이터 (Hierarchy)
- 승자: WITH 절 (Recursive CTE)
- 분석: 카테고리 트리나 댓글의 대댓글 구조를 탐색할 때, 일반 VIEW는 한계가 있습니다. WITH RECURSIVE를 사용하면 별도의 애플리케이션 로직 없이 SQL 한 번으로 트리 전체를 스캔할 수 있습니다.
4. 핵심 요약 테이블 (Detail Version)
| 상세 항목 | VIEW (뷰) | WITH 절 (CTE) |
| 저장 위치 | Data Dictionary (Disk) | Memory (Execution time) |
| 인덱스 활용 | 원본 인덱스 병합 가능 (Merge) | 임시 테이블 생성 시 인덱스 소실 가능 |
| 재귀 호출 | 지원하지 않음 | 지원함 (Recursive CTE) |
| 데이터 수정 | 일부 가능 (Updatable View) | 불가능 (Read-only) |
| 권한 관리 | 객체 단위 권한 부여 가능 | 권한 제어 불가 (원본 권한 의존) |
5. VIEW,WITH선택의 기준?
결국 "어디까지 공유할 것인가?"가 선택의 기준입니다.
- 전사적 표준 모든 부서가 똑같이 정의해야 하는 비즈니스 로직(예: '순매출'의 정의)은 VIEW를 사용
- 쿼리별 특수 로직: 특정 보고서나 특정 기능을 위해서만 잠깐 필요한 복잡한 가공 과정은 WITH 절 사용
VIEW는 여러 곳에서 동일하게 사용해야 하는 데이터의 기준을 정의하는 역할을 하고,
WITH 절은 한 번의 쿼리 안에서 복잡한 처리 과정을 읽기 쉽게 나누기 위한 도구입니다.
시리즈를 마치며
지금까지 MySQL의 가상 테이블 기술인 VIEW와 WITH 절을 3회에 걸쳐 알아보았습니다. 가상 테이블의 차이점과 어떤 기술을 알맞은 상황에서 사용할것인지 잘 생각해서 실무나 현업에서 적용하시길 바라겠습니다.
'DB > Mysql' 카테고리의 다른 글
| [MySQL 심층 탐구] SQL로 무한 루프를? WITH RECURSIVE(재귀 쿼리) 완벽 마스터 (0) | 2026.01.02 |
|---|---|
| SQL 가상 테이블 : VIEW vs CTE vs Subquery, 최종 설계 및 선택 가이드 (0) | 2026.01.02 |
| [MySQL 심층 탐구] 쿼리의 품격을 높이는 'WITH' 절 (CTE) 완벽 가이드 (0) | 2025.12.31 |
| [MySQL 심층 탐구] 가상 테이블 'VIEW', 왜 사용하고 어떻게 설계해야 하는가? (0) | 2025.12.31 |
| 서브쿼리를 쓰지 말아야 할 기술적 이유와 근본적 설계 (0) | 2025.12.30 |
