인덱스, 파티셔닝, 뷰, ACID
80 SQL Interview Questions for Data Engineers (Real Asks, 2026) — DataVidhya blog Advanced Data Engineering SQL, Q21-27 (pp.10-13)
이 모듈을 다 읽으면
- 인덱스가 읽기/쓰기 성능에 미치는 상반된 영향을 설명할 수 있다
- 파티셔닝이 파티션 프루닝을 통해 성능을 개선하는 원리를 설명할 수 있다
- 뷰와 구체화된 뷰(Materialized View)의 차이와 트레이드오프를 설명할 수 있다
- ACID 4대 속성을 정의하고 각각이 보장하는 바를 설명할 수 있다
인덱스와 파티셔닝이 쿼리 성능에 미치는 영향, 뷰와 구체화된 뷰의 차이, 트랜잭션의 ACID 속성, 그리고 ROW_NUMBER를 이용한 중복 제거 패턴을 다룬다. 정규화/역정규화/스타 스키마는 07~09번 모델링 모듈에서 더 깊이 다루므로 여기서는 반복하지 않는다.
인덱스 — 읽기는 빠르게, 쓰기는 느리게
인덱스는 전체 테이블 스캔보다 훨씬 빠르게 행을 찾을 수 있도록 돕는 자료구조로, 대표적으로 B-Tree 구조를 사용한다. 인덱스는 SELECT 성능을 극적으로 끌어올리지만, 그 대가로 INSERT/UPDATE/DELETE 때마다 인덱스 자체도 함께 갱신해야 하므로 쓰기 성능은 떨어진다.
— 정정: 인덱스가 '전형적으로 B-Tree'라는 설명은 맞지만 유일한 형태는 아니다. 정확한 일치 검색에 특화된 해시 인덱스(PostgreSQL의 HASH 인덱스), 카디널리티가 낮은 컬럼에 유리한 비트맵 인덱스(Oracle, Redshift 계열), 전문 검색용 GIN, 공간·범위 검색용 GiST (PostgreSQL) 등 목적에 따라 다양한 인덱스 구조가 존재한다. B-Tree는 범위 조건과 정렬에 강한 범용 기본값일 뿐이다.
핵심 포인트
- 인덱스는 읽기(SELECT) 성능을 크게 높이지만 매 쓰기 연산마다 갱신 비용이 추가돼 쓰기 성능을 떨어뜨린다.
- B-Tree가 가장 흔한 인덱스 구조지만 유일한 형태는 아니다 — 해시, 비트맵, GIN/GiST 등 목적별 인덱스가 따로 존재한다 — 정정.
파티셔닝, 클러스터드 vs 논클러스터드 인덱스
파티셔닝은 큰 테이블을 날짜나 지역 같은 특정 컬럼 기준으로 물리적으로 더 작은 조각으로 나누는 것이다. 쿼리의 필터 조건이 파티션 키와 일치하면 엔진은 관련 없는 파티션을 아예 건너뛰는 '파티션 프루닝(partition pruning)'을 수행해 스캔량을 크게 줄인다.
클러스터드 인덱스는 디스크 상의 실제 물리적 저장 순서 자체를 결정하므로 테이블당 하나만 존재할 수 있다. 논클러스터드 인덱스는 데이터 행을 가리키는 포인터만 별도로 저장하는 객체이므로, 서로 다른 쿼리 패턴을 지원하기 위해 여러 개를 만들 수 있다.
핵심 포인트
- 파티셔닝은 테이블을 물리적으로 분할해, 필터 조건과 일치하는 파티션만 스캔하는 파티션 프루닝을 가능하게 한다.
- 클러스터드 인덱스는 물리적 저장 순서를 결정하며 테이블당 1개뿐이고, 논클러스터드 인덱스는 여러 개 만들 수 있다.
뷰 vs 구체화된 뷰(Materialized View)
뷰(View)는 저장된 SQL 쿼리로 이루어진 '가상 테이블'이며 데이터 자체를 저장하지 않는다. 복잡한 조인을 단순화해 최종 사용자에게 보여주거나, 특정 컬럼만 노출해 보안 계층을 제공하는 용도로 쓰인다.
구체화된 뷰는 쿼리 결과를 실제로 디스크에 물리적으로 저장한다. 복잡한 분석 쿼리에서 큰 성능 이득을 주지만, 원본 테이블이 바뀌어도 저장된 데이터가 오래된 상태(stale)로 남지 않도록 '리프레시' 전략이 필요하다. BigQuery 같은 일부 엔진은 옵티마이저가 원본 쿼리를 구체화된 뷰로 재작성할 수 있다고 판단하면, 추가 컴퓨팅 비용 없이 구체화된 뷰의 결과를 그대로 서빙하기도 한다.
핵심 포인트
- 뷰는 데이터를 저장하지 않는 가상 테이블이고, 구체화된 뷰는 쿼리 결과를 실제로 물리 저장한다.
- 구체화된 뷰는 성능이 좋지만 원본 데이터 변경 시 리프레시 전략이 필요하다.
ROW_NUMBER로 중복 삭제, 그리고 ACID
중복 행 중 하나만 남기고 지우는 가장 견고한 방법은 CTE와 ROW_NUMBER()를 결합하는 것이다. 중복을 정의하는 컬럼들로 PARTITION BY 하고 고유 ID로 ORDER BY 한 뒤, 부여된 행 번호가 1보다 큰 행만 DELETE 한다.
ACID는 트랜잭션 신뢰성을 보장하는 4대 속성이다. Atomicity(원자성)는 트랜잭션이 전부 성공하거나 전부 실패함을, Consistency(일관성)는 트랜잭션 전후로 데이터가 항상 유효한 상태를 유지함을, Isolation(격리성)은 동시에 실행되는 트랜잭션들이 서로 간섭하지 않음을, Durability(지속성)는 커밋된 데이터가 시스템 장애 후에도 보존됨을 의미한다.
핵심 포인트
- ROW_NUMBER() OVER (PARTITION BY 중복기준 ORDER BY 고유ID)로 행 번호를 매긴 뒤 1보다 큰 행만 삭제하는 것이 표준 중복 제거 패턴이다.
- ACID = Atomicity(원자성) + Consistency(일관성) + Isolation(격리성) + Durability(지속성).