Unisquads
로그인
홈
이용약관·개인정보처리방침·콘텐츠정책·© 2026 Unisquads
이용약관·개인정보처리방침·콘텐츠정책
© 2026 Unisquads. All rights reserved.

뷰 및 인덱스 (r1)

이 문서의 과거 버전 (r1)을 보고 있습니다. 수정일: 2026.02.14 21:42

뷰 및 인덱스

분류

데이터베이스 관리 시스템(DBMS)

주요 목적

데이터 접근성 향상, 보안, 성능 최적화

관련 개념

테이블, 쿼리, 스키마

주요 구현 시스템

Oracle, MySQL, PostgreSQL, Microsoft SQL Server

기술 상세

뷰(View) 정의

하나 이상의 테이블에서 유도된 가상 테이블

뷰의 주요 특징

논리적 데이터 독립성 제공, 복잡한 쿼리 단순화, 접근 제어(보안) 용이

뷰의 종류

단순 뷰, 복합 뷰, 인라인 뷰, 머티리얼라이즈드 뷰(Materialized View)

인덱스(Index) 정의

테이블의 검색 속도를 높이기 위한 자료 구조

인덱스의 주요 특징

검색(Read) 성능 향상, 삽입/갱신/삭제(Write) 성능 저하 가능성

인덱스의 종류

B-트리 인덱스, 비트맵 인덱스, 해시 인덱스, 클러스터형 인덱스, 비클러스터형 인덱스

인덱스 생성 기준

카디널리티가 높은 열, WHERE, JOIN, ORDER BY 절에 자주 사용되는 열

뷰와 인덱스의 관계

머티리얼라이즈드 뷰는 인덱스를 가질 수 있음, 인덱스를 활용한 뷰 쿼리 성능 향상

관리 및 유지보수

인덱스 리빌드/재구성, 뷰 정의 변경, 통계 정보 갱신

1. 개요

뷰와 인덱스는 관계형 데이터베이스 관리 시스템에서 데이터 접근 효율성을 높이고 논리적 데이터 추상화를 제공하는 핵심 객체이다. 이들은 데이터베이스의 성능과 사용 편의성을 결정하는 중요한 요소로 작동한다.

뷰는 하나 이상의 기본 테이블로부터 유도된 가상 테이블이다. 실제 데이터를 저장하지 않지만, 사용자에게 특정 조건에 맞는 데이터의 논리적 뷰를 제공한다. 반면, 인덱스는 테이블 내 데이터의 물리적 배치와 직접적으로 관련된 구조로, 책의 색인과 같이 특정 데이터를 빠르게 찾기 위해 사용된다.

이 둘의 근본적인 차이는 저장 방식과 목적에 있다. 뷰는 데이터 자체를 저장하지 않는 쿼리의 결과셋에 가깝고, 주로 보안 강화와 쿼리 단순화를 목표로 한다. 인덱스는 디스크 공간을 추가로 사용하여 데이터의 물리적 위치 정보를 저장하며, 검색 및 정렬 속도를 비약적으로 향상시키는 것이 주된 목적이다.

뷰와 인덱스는 상호 보완적으로 활용될 수도 있다. 예를 들어, 자주 조회되는 복잡한 뷰에 인덱싱된 뷰를 생성하여 성능을 개선하는 방식이다. 데이터베이스 시스템별로 이들의 구현과 최적화 전략에는 미묘한 차이가 존재한다.

2. 뷰(View)의 개념

뷰(View)는 데이터베이스에서 하나 이상의 기본 테이블로부터 유도된 가상 테이블이다. 실제 데이터를 저장하지 않고, 쿼리를 통해 정의된 논리적인 테이블 구조를 제공한다. 사용자는 뷰를 마치 실제 테이블처럼 조회할 수 있지만, 그 뒤에는 데이터를 가져오기 위한 SQL 문장이 존재한다. 뷰의 주요 목적은 데이터 접근을 단순화하고, 보안을 강화하며, 복잡한 쿼리 로직을 추상화하는 데 있다.

가상 테이블로서의 뷰는 몇 가지 특징을 가진다. 뷰는 데이터 독립성을 제공하여 기본 테이블의 구조가 변경되더라도 뷰를 사용하는 응용 프로그램에는 영향을 최소화할 수 있다. 또한, 뷰는 특정 사용자나 역할에게 필요한 열과 행만을 보여줌으로써 데이터 접근 권한을 효과적으로 제어하는 수단이 된다. 예를 들어, 직원 테이블에서 급여 정보를 제외한 나머지 열만 보여주는 뷰를 생성하여 일반 사용자에게 접근 권한을 부여할 수 있다.

뷰의 장점은 다양하다. 복잡한 조인이나 집계 연산을 포함하는 쿼리를 뷰로 정의하면, 사용자는 간단한 SELECT 문으로 결과를 얻을 수 있어 생산성이 향상된다. 데이터 보안 측면에서는 민감한 데이터를 직접 노출시키지 않고 필터링된 뷰를 통해 접근하도록 할 수 있다. 활용 사례로는 자주 사용하는 보고서용 쿼리를 뷰로 만들어 두거나, 여러 테이블을 통합한 논리적 인터페이스를 제공하는 경우가 있다.

특징

설명

물리적 저장

데이터를 실제로 저장하지 않음 (인덱싱된 뷰 제외)

데이터 독립성

기본 테이블의 스키마 변경으로부터 응용 프로그램을 보호

보안 강화

특정 열 또는 행에 대한 접근 제한 가능

쿼리 단순화

복잡한 쿼리 로직을 추상화하여 사용 편의성 제공

그러나 뷰는 성능 측면에서 고려사항이 있다. 뷰를 조회할 때마다 내부에 정의된 쿼리가 실행되므로, 복잡한 뷰를 과도하게 사용하면 성능 저하가 발생할 수 있다. 또한, 모든 뷰가 업데이트 가능한 것은 아니며, 특정 조건을 만족해야 기본 테이블의 데이터를 변경하는 INSERT, UPDATE, DELETE 연산이 가능하다.

2.1. 정의와 목적

뷰는 데이터베이스에서 하나 이상의 기본 테이블로부터 유도된 가상 테이블이다. 물리적으로 데이터를 저장하지 않고, 쿼리를 통해 정의된 논리적인 테이블 구조를 제공한다. 사용자는 뷰를 마치 실제 테이블처럼 조회할 수 있으며, 이를 통해 복잡한 데이터 접근을 단순화하고 보안을 강화하는 것이 주요 목적이다.

뷰의 핵심 목적은 다음과 같다. 첫째, 복잡성을 감추고 사용자에게 필요한 데이터만을 명확하게 제공하여 데이터 접근을 단순화한다. 둘째, 기본 테이블의 특정 열이나 행에 대한 접근만을 허용함으로써 데이터 보안을 구현한다. 셋째, 애플리케이션의 논리적 독립성을 유지한다. 기본 테이블의 구조가 변경되더라도 뷰 인터페이스를 통해 애플리케이션에 영향을 최소화할 수 있다.

2.2. 가상 테이블로서의 특징

뷰는 하나 이상의 기본 테이블로부터 유도된 가상 테이블이다. 물리적으로 데이터를 저장하지 않으며, 데이터베이스 관리 시스템에 저장된 뷰 정의에 따라 쿼리 시점에 실시간으로 결과를 생성한다. 사용자나 응용 프로그램은 실제 테이블과 동일한 방식으로 뷰를 조회하거나, 일부 경우에는 수정할 수도 있다.

뷰의 주요 특징은 논리적 데이터 독립성을 제공한다는 점이다. 기본 테이블의 구조가 변경되더라도, 뷰를 통해 데이터를 접근하는 응용 프로그램의 인터페이스는 변경되지 않을 수 있다. 또한, 복잡한 조인이나 집계 함수를 포함하는 쿼리를 뷰로 정의하면, 사용자는 단순한 SELECT 문으로 동일한 결과를 얻을 수 있어 편의성이 크게 향상된다.

보안 측면에서 뷰는 중요한 역할을 한다. 특정 열이나 행만을 사용자에게 노출시키는 접근 제어 수단으로 활용될 수 있다. 예를 들어, 직원 테이블에서 급여 정보를 제외한 나머지 열만 보여주는 뷰를 생성함으로써 민감한 데이터에 대한 접근을 차단할 수 있다.

특징

설명

물리적 저장 없음

데이터를 별도로 저장하지 않고, 정의된 쿼리의 실행 결과를 보여준다.

논리적 추상화

복잡한 데이터 모델을 단순화된 인터페이스로 제공한다.

데이터 독립성

기본 테이블의 물리적 구조 변경으로부터 응용 프로그램을 보호한다.

보안 강화

특정 사용자에게 필요한 데이터만을 선별하여 제공할 수 있다.

그러나 뷰는 가상 테이블이기 때문에 성능 상의 고려사항이 존재한다. 뷰를 조회할 때마다 내부적으로 정의된 쿼리가 실행되어 결과를 만들어내므로, 매우 복잡한 쿼리로 정의된 뷰를 빈번히 사용하면 시스템 성능에 부하를 줄 수 있다. 이러한 문제를 해결하기 위해 인덱싱된 뷰와 같은 최적화 기법이 사용되기도 한다.

2.3. 장점과 활용 사례

뷰는 데이터베이스 사용자와 애플리케이션 개발자에게 여러 가지 실질적인 이점을 제공한다. 가장 큰 장점은 논리적 데이터 독립성을 보장한다는 점이다. 기본 테이블의 구조가 변경되더라도, 이를 참조하는 뷰의 정의만 적절히 수정하면 뷰를 사용하는 쿼리나 애플리케이션 코드를 변경할 필요가 없다. 이는 시스템 유지보수와 확장성을 크게 향상시킨다.

보안 강화는 또 다른 주요 장점이다. 민감한 열을 제외하거나, 특정 행만 필터링하여 사용자나 역할별로 맞춤형 데이터 접근 권한을 부여할 수 있다. 예를 들어, 직원 테이블에서 급여 정보를 제외한 뷰를 생성하여 일반 부서원에게 제공하거나, 특정 지역의 매출 데이터만 보여주는 뷰를 생성할 수 있다.

뷰는 복잡성을 감추고 쿼리 재사용성을 높이는 데도 유용하다. 자주 사용하는 복잡한 조인이나 집계 함수 쿼리를 뷰로 정의하면, 사용자는 마치 단일 테이블을 조회하는 것처럼 간단한 문법으로 데이터에 접근할 수 있다. 이는 개발 생산성을 높이고 오류 가능성을 줄인다.

활용 사례

설명

보안 및 접근 제어

사용자별로 볼 수 있는 데이터 범위를 제한하는 가상 테이블을 제공한다.

복잡한 쿼리 단순화

다중 테이블 조인이나 복잡한 계산 로직을 캡슐화하여 사용자에게 투명하게 한다.

호환성 유지

기존 테이블 스키마를 변경할 때, 이전 스키마를 모방한 뷰를 제공하여 레거시 애플리케이션과의 호환성을 유지한다[1].

사용자 맞춤형 데이터 표현

서로 다른 사용자 그룹(예: 관리자, 고객, 파트너)에게 필요한 데이터 형식과 구조를 별도의 뷰로 제공한다.

3. 인덱스(Index)의 개념

인덱스는 데이터베이스에서 테이블의 검색 속도를 향상시키기 위해 사용하는 자료 구조이다. 책의 색인과 유사한 역할을 하여, 특정 컬럼 값을 기반으로 데이터의 물리적 위치를 빠르게 찾을 수 있도록 돕는다. 전체 테이블을 순차적으로 검색(풀 테이블 스캔)하는 것보다 효율적으로 원하는 레코드에 접근할 수 있게 해준다. 인덱스는 주로 SELECT 쿼리의 WHERE 절이나 JOIN 조건에 자주 사용되는 컬럼에 생성한다.

인덱스의 내부 구조는 데이터베이스 시스템에 따라 다양하다. 가장 일반적인 구조는 B-Tree 계열(B+Tree)이다. B-Tree 인덱스는 데이터를 정렬된 상태로 유지하며, 루트, 브랜치, 리프 노드로 구성되어 범위 검색(BETWEEN, 부등호)과 부분 일치 검색에 효율적이다. 다른 구조로는 해시 인덱스가 있다. 해시 인덱스는 키 값을 해시 함수로 계산하여 특정 슬롯에 매핑하므로, 동등 비교(=) 검색은 매우 빠르지만 범위 검색에는 사용할 수 없다. 또한, 전문 텍스트 검색을 위한 풀텍스트 인덱스나 공간 데이터를 위한 공간 인덱스 등 특수한 목적의 인덱스도 존재한다.

인덱스는 물리적 데이터 재구성 여부에 따라 크게 두 가지 유형으로 구분된다. 클러스터형 인덱스는 테이블의 데이터 행 자체를 인덱스 키 값의 순서에 따라 물리적으로 재배열한다. 따라서 한 테이블에 하나만 생성할 수 있으며, 테이블의 데이터는 그 자체가 정렬된 인덱스가 된다. 반면, 비클러스터형 인덱스는 데이터 행의 물리적 순서를 변경하지 않고, 별도의 구조에 인덱스 키 값과 해당 데이터 행을 찾을 수 있는 포인터(주로 ROWID 또는 클러스터형 인덱스 키)를 저장한다. 하나의 테이블에 여러 개의 비클러스터형 인덱스를 생성하는 것이 가능하다.

3.1. 정의와 필요성

인덱스는 데이터베이스 테이블의 검색 속도를 향상시키기 위해 사용하는 자료 구조이다. 특정 컬럼(열)의 값을 기반으로 데이터의 물리적 위치 정보를 빠르게 찾을 수 있도록 정렬된 목록을 생성한다. 테이블에 직접 데이터를 저장하는 것이 아니라, 책의 색인과 유사하게 검색 키와 해당 데이터 행에 대한 포인터를 저장하는 별도의 객체이다.

인덱스의 필요성은 대량의 데이터를 효율적으로 관리하기 위해 발생한다. 풀 테이블 스캔은 모든 데이터 행을 순차적으로 검사하기 때문에 데이터 양이 많아질수록 쿼리 성능이 급격히 저하된다. 인덱스는 이러한 문제를 해결하여 SELECT 문의 WHERE 절이나 JOIN 조건에 사용된 컬럼에 대한 검색, 정렬(ORDER BY), 그룹화(GROUP BY) 작업의 성능을 비약적으로 향상시킨다.

인덱스가 효율적인 주요 작업과 그렇지 않은 작업은 다음과 같이 구분된다.

효율적인 작업

비효율적인 작업

특정 값 검색 (등호 비교)

대량의 데이터 삽입(INSERT)

범위 검색 (부등호, BETWEEN)

대량의 데이터 갱신(UPDATE)

정렬된 결과 출력

DELETE 작업이 빈번한 경우

테이블 간 조인 조건 활용

카디널리티가 매우 낮은 컬럼(예: 성별)

그러나 인덱스는 저장 공간을 추가로 소모하며, 데이터 변경 작업(INSERT, UPDATE, DELETE)이 발생할 때마다 인덱스 구조도 함께 갱신되어야 하므로 오버헤드가 발생한다. 따라서 모든 컬럼에 인덱스를 생성하는 것은 오히려 전체 시스템 성능을 저하시킬 수 있다. 검색 빈도, 데이터 분포, 테이블의 크기 등을 고려하여 적절한 컬럼을 선정하여 생성하는 것이 중요하다.

3.2. 인덱스의 구조 (B-Tree, 해시 등)

인덱스의 구조는 데이터를 효율적으로 조회하기 위해 사용되는 물리적 저장 및 조직화 방식을 의미한다. 가장 일반적인 구조는 B-Tree이며, 그 외에도 해시 인덱스, 비트맵 인덱스, 전문 인덱스 등이 특정 데이터베이스 시스템이나 사용 사례에 따라 활용된다.

구조 유형

주요 특징

적합한 쿼리 패턴

주요 데이터베이스 예시

B-Tree (밸런스드 트리)

계층적 트리 구조, 범위 검색에 효율적

동등 비교(=), 범위 검색(BETWEEN, >, <), 정렬(ORDER BY)

MySQL의 InnoDB, PostgreSQL, Oracle, SQL Server

해시 인덱스

키 값의 해시 함수 결과를 사용, 정확한 일치 검색에 매우 빠름

동등 비교(=)만 가능, 범위 검색 불가

MySQL의 MEMORY 스토리지 엔진

비트맵 인덱스

각 고유 값에 대해 비트맵(비트 배열)을 생성

카디널리티가 낮은(중복도 높은) 열에 대한 다중 조건 조회

Oracle (주로 데이터 웨어하우스)

전문 인덱스 (Full-Text)

텍스트 데이터의 단어(토큰)를 인덱싱

키워드 검색, 자연어 검색, LIKE '%...%'보다 효율적

MySQL의 FULLTEXT, PostgreSQL의 GIN/GiST

B-Tree는 루트 노드, 브랜치 노드, 리프 노드로 구성된 균형 잡힌 트리 구조이다. 데이터는 정렬된 상태로 리프 노드에 저장되며, 각 노드는 여러 키와 자식 노드에 대한 포인터를 가진다. 이 구조 덕분에 대량의 데이터에서도 검색, 삽입, 삭제 연산이 로그 시간(O(log n)) 내에 수행된다. 대부분의 관계형 데이터베이스 시스템의 기본 인덱스 구조이다. 해시 인덱스는 메모리 기반 테이블에서 매우 빠른 점 조회를 제공하지만, 해시 충돌과 범위 검색 불가라는 한계가 있다. 비트맵 인덱스는 성별이나 상태 코드처럼 고유 값의 종류가 적은 열에서 AND, OR 연산이 많은 복합 조건 쿼리에 강점을 보인다.

3.3. 클러스터형 vs 비클러스터형 인덱스

클러스터형 인덱스는 테이블의 물리적 데이터 행 자체를 인덱스 키 값의 순서에 따라 정렬하여 저장하는 방식이다. 이는 사전의 페이지와 유사한 구조로, 데이터 자체가 순서대로 배열된다. 따라서 한 테이블에는 오직 하나의 클러스터형 인덱스만 생성할 수 있다. 데이터가 물리적으로 정렬되어 있기 때문에 범위 검색이 매우 효율적이며, 기본 키는 대부분 자동으로 클러스터형 인덱스로 생성된다. 그러나 데이터 삽입, 삭제, 갱신 시 물리적 재정렬이 발생할 수 있어 성능에 영향을 미칠 수 있다.

반면, 비클러스터형 인덱스는 데이터 행의 물리적 순서를 변경하지 않고 별도의 인덱스 구조를 생성한다. 이는 책의 색인과 같아서, 색인 항목은 정렬되어 있지만 실제 내용은 책에서 별도의 페이지에 흩어져 있다. 하나의 테이블에 여러 개의 비클러스터형 인덱스를 생성할 수 있다. 인덱스 자체는 키 값과 해당 데이터 행의 위치를 가리키는 포인터로 구성된다. 특정 값을 조회할 때는 빠르지만, 범위 스캔 시 클러스터형 인덱스보다 일반적으로 느릴 수 있다.

두 인덱스의 주요 차이점을 비교하면 다음과 같다.

특성

클러스터형 인덱스

비클러스터형 인덱스

수량

테이블당 1개

테이블당 여러 개

데이터 저장 방식

데이터 행을 물리적으로 정렬

별도 인덱스 구조 생성, 데이터는 원래 순서 유지

조회 성능

범위 검색에 매우 효율적

특정 값 조회에 효율적

기본 키 연관

일반적으로 기본 키로 생성됨

기본 키와 무관하게 생성 가능

저장 공간

추가 공간이 거의 필요 없음

별도의 인덱스 구조를 저장할 공간 필요

적절한 인덱스 선택은 데이터의 특성과 쿼리 패턴에 달려 있다. 자주 검색되고 범위 질의가 많은 컬럼에는 클러스터형 인덱스를, 다양한 조건으로 자주 필터링되는 여러 컬럼에는 비클러스터형 인덱스를 적용하는 것이 일반적이다. 또한 비클러스터형 인덱스는 클러스터형 인덱스 키를 포인터로 포함하는 경우가 많아, 클러스터형 인덱스의 선택이 전체적인 인덱스 전략에 미치는 영향이 크다.

4. 뷰와 인덱스의 차이점

뷰와 인덱스는 모두 데이터베이스 성능과 데이터 접근 효율성을 높이는 데 사용되지만, 그 본질과 목적, 동작 방식에서 근본적인 차이를 보인다.

가장 핵심적인 차이는 데이터의 물리적 저장과 관련이 있다. 인덱스는 테이블의 데이터에 대한 물리적인 정렬 또는 빠른 검색 경로를 제공하는 별도의 데이터 구조이다. 반면, 뷰는 물리적으로 데이터를 저장하지 않는 가상 테이블로, 하나 이상의 기본 테이블에 대한 쿼리 결과를 논리적인 형태로 정의한다. 따라서 인덱스를 생성하면 디스크 공간을 추가로 사용하지만, 뷰는 쿼리 정의만 저장하여 공간을 거의 차지하지 않는다.

주요 목적과 역할도 명확히 구분된다. 인덱스의 주요 목적은 데이터 검색 속도를 향상시키는 것이다. 특정 열을 기준으로 데이터를 정렬하거나 해시하여, 풀 테이블 스캔을 피하고 빠르게 원하는 행을 찾을 수 있게 돕는다. 뷰의 주된 목적은 데이터 접근을 단순화하고 보안을 강화하는 데 있다. 복잡한 조인이나 필터링 로직을 뷰로 캡슐화하여 사용자에게 투명하게 제공하거나, 특정 열이나 행만 노출시켜 데이터 접근 권한을 제어할 수 있다.

아래 표는 두 개념의 주요 차이점을 요약하여 보여준다.

구분

뷰 (View)

인덱스 (Index)

본질

저장된 쿼리를 기반으로 한 가상 테이블

데이터 검색 속도를 높이는 물리적 데이터 구조

데이터 저장

데이터를 물리적으로 저장하지 않음 (쿼리 정의만 저장)

데이터를 물리적으로 저장하거나 정렬 정보를 유지함

주요 목적

데이터 접근 단순화, 논리적 데이터 추상화, 보안

데이터 검색 및 정렬 성능 최적화

성능 영향

직접적인 성능 향상 도구는 아님. 오히려 복잡한 뷰는 성능 저하를 초래할 수 있음

특정 조건의 검색 및 정렬 성능을 극적으로 향상시킴

데이터 갱신

기본 테이블의 데이터 변경 시 자동으로 반영됨. 단, 일부 뷰는 갱신이 제한적일 수 있음

기본 테이블의 데이터가 변경되면 인덱스도 함께 유지 관리되어야 함

생성/관리

CREATE VIEW 문으로 생성, DROP VIEW로 삭제

CREATE INDEX 문으로 생성, DROP INDEX로 삭제

요약하면, 뷰는 '어떤 데이터를 어떻게 보여줄 것인가'에 대한 논리적 계층이라면, 인덱스는 '데이터를 어떻게 빠르게 찾을 것인가'에 대한 물리적 최적화 기법이다. 이 둘은 상호 보완적으로 사용될 수 있으며, 특히 인덱싱된 뷰는 뷰에 인덱스를 적용하여 두 기술의 장점을 결합한 특수한 형태이다.

5. 뷰의 생성과 관리

뷰는 CREATE VIEW 문을 사용하여 생성한다. 기본 구문은 CREATE VIEW 뷰_이름 AS SELECT 문이다. SELECT 문은 하나 이상의 기본 테이블이나 다른 뷰를 참조할 수 있으며, 필요에 따라 WHERE, JOIN, GROUP BY 등의 절을 포함한다. 생성된 뷰는 권한이 부여된 사용자에게 마치 실제 테이블처럼 조회할 수 있는 객체가 된다.

뷰의 정의를 변경하려면 ALTER VIEW 문을 사용하여 SELECT 문을 재정의한다. 뷰를 삭제할 때는 DROP VIEW 문을 사용한다. 일부 데이터베이스 시스템은 CREATE OR REPLACE VIEW와 같은 문법을 지원하여 정의를 편리하게 갱신할 수 있도록 한다.

뷰는 주로 복잡한 쿼리를 단순화하거나, 데이터 접근을 제어하는 데 사용되지만, 성능에 주의해야 한다. 뷰 자체는 데이터를 저장하지 않으므로, 뷰를 조회할 때마다 내부의 SELECT 문이 실행되어 기본 테이블에서 데이터를 가져온다. 따라서 복잡한 조인이나 집계 연산을 포함하는 뷰를 빈번히 사용하면 성능 저하가 발생할 수 있다. 이를 완화하기 위해 일부 데이터베이스 시스템은 인덱싱된 뷰 또는 물질화된 뷰 기능을 제공한다.

뷰 관리는 데이터 무결성과도 연관된다. 단순 뷰(하나의 테이블에서 파생되고 특정 조건을 만족하는 경우)에 대해서는 INSERT, UPDATE, DELETE 연산이 가능할 수 있지만, 복잡한 뷰에 대한 데이터 변경 작업은 제한적이거나 불가능하다. 관리자는 뷰의 생성 목적과 구조를 고려하여 적절한 접근 권한을 설정해야 한다.

5.1. 생성 구문 (CREATE VIEW)

뷰는 CREATE VIEW 문을 사용하여 생성한다. 기본적인 구문은 다음과 같다.

```sql

CREATE VIEW 뷰_이름 [(열_이름1, 열_이름2, ...)]

AS

SELECT 문

[WITH CHECK OPTION];

```

CREATE VIEW 키워드 뒤에 생성할 뷰의 이름을 지정한다. 선택적으로 괄호 안에 열 이름 목록을 명시할 수 있으며, 생략하면 SELECT 문이 반환하는 열의 이름이 그대로 사용된다. AS 키워드 뒤에는 뷰를 정의하는 SELECT 문을 작성한다. 이 SELECT 문은 하나 이상의 기본 테이블이나 다른 뷰를 참조할 수 있다. 선택적인 WITH CHECK OPTION 절을 추가하면, 뷰를 통해 데이터를 변경할 때 뷰 정의의 SELECT 문 조건을 만족시키지 않는 데이터 수정을 방지한다[2].

생성 예시는 다음과 같다. employees 테이블에서 부서 번호가 10인 사원의 사번과 이름으로 구성된 뷰를 만드는 경우다.

```sql

CREATE VIEW emp_dept10 (emp_id, emp_name)

AS

SELECT employee_id, last_name

FROM employees

WHERE department_id = 10;

```

뷰를 생성할 때는 몇 가지 제약 사항을 고려해야 한다. 일부 데이터베이스 관리 시스템에서는 ORDER BY 절을 뷰 정의에 사용하는 것을 허용하지 않거나, 임시 테이블을 참조하는 것을 제한할 수 있다. 또한, 뷰의 SELECT 문에 집계 함수나 GROUP BY 절, DISTINCT 키워드가 포함된 경우 데이터 변경 작업(INSERT, UPDATE, DELETE)이 제한된다.

5.2. 수정 및 삭제

뷰를 수정하는 방법은 데이터베이스 관리 시스템에 따라 다르다. 일반적으로 CREATE VIEW 문으로 생성된 뷰의 정의를 변경하려면 ALTER VIEW 문을 사용한다. 이 명령어를 통해 뷰의 SELECT 쿼리 로직을 수정할 수 있지만, 뷰가 참조하는 기본 테이블의 스키마 변경과는 무관하다. 일부 시스템에서는 CREATE OR REPLACE VIEW 문을 사용하여 기존 뷰를 새 정의로 완전히 대체하는 방식도 지원한다.

뷰를 삭제할 때는 DROP VIEW 문을 사용한다. 이 명령어는 데이터베이스에서 뷰의 정의를 완전히 제거하지만, 뷰가 기반으로 하는 실제 테이블의 데이터에는 영향을 미치지 않는다. 삭제 작업을 수행하기 전에 해당 뷰에 의존하는 다른 데이터베이스 객체(예: 다른 뷰나 저장 프로시저)가 있는지 확인하는 것이 중요하다. 의존성이 있는 경우 삭제가 실패하거나 경고가 발생할 수 있다.

뷰의 관리 작업 중에는 권한 관리도 포함된다. 뷰는 기본 테이블에 대한 접근 권한을 통제하는 보안 계층 역할을 하므로, 뷰에 대한 사용자 권한을 GRANT 및 REVOKE 문을 통해 적절히 부여하거나 회수해야 한다.

작업

SQL 명령어

주요 목적/효과

뷰 정의 변경

ALTER VIEW 또는 CREATE OR REPLACE VIEW

뷰를 구성하는 쿼리 문장을 수정

뷰 제거

DROP VIEW [뷰 이름]

데이터베이스에서 뷰의 메타데이터 정의 삭제

권한 부여

GRANT SELECT ON [뷰 이름] TO [사용자]

특정 사용자에게 뷰 조회 권한 부여

권한 회수

REVOKE SELECT ON [뷰 이름] FROM [사용자]

부여된 뷰 조회 권한을 취소

5.3. 성능 고려사항

뷰는 기본적으로 쿼리의 재사용성을 높이지만, 성능에 직접적인 이점을 제공하지는 않는다. 뷰를 조회할 때마다 내부에 정의된 SELECT 문이 매번 실행되어 결과 집합을 생성한다. 따라서 복잡한 조인이나 집계 함수를 포함하는 뷰를 빈번히 사용하면 오히려 성능 저하를 초래할 수 있다. 특히 뷰가 다른 뷰를 중첩하여 참조하는 경우, 실행 계획이 비효율적으로 구성될 위험이 있다.

성능을 개선하기 위한 주요 접근법은 인덱싱된 뷰를 활용하는 것이다. 그러나 이는 모든 데이터베이스 관리 시스템에서 지원하지 않으며, SQL Server나 Oracle의 Materialized View와 같이 특정 시스템에 한정된 기능이다. 일반 뷰의 성능을 최적화하려면 뷰 정의 내의 쿼리 자체를 효율적으로 작성해야 한다. 불필요한 컬럼을 제거하고, 적절한 조인 조건을 사용하며, 가능하면 필터 조건(WHERE 절)을 뷰 정의에 포함시키는 것이 좋다.

뷰 사용 시 주의해야 할 또 다른 성능 요소는 데이터 최신성과의 절충 관계이다. 인덱싱된 뷰나 Materialized View는 물리적으로 데이터를 저장하여 조회 성능을 극적으로 향상시키지만, 기본 테이블의 데이터 변경 사항을 실시간으로 반영하지 못할 수 있다. 이는 성능 향상과 데이터 실시간성 사이의 트레이드오프를 요구한다. 시스템의 요구사항에 따라 적절한 뷰 유형을 선택하는 것이 중요하다.

마지막으로, 뷰는 쿼리 최적화기의 실행 계획 수립에 영향을 줄 수 있다. 일부 복잡한 뷰는 최적화기가 효율적인 접근 경로를 찾는 것을 방해할 수 있다. 따라서 성능이 중요한 쿼리 경로에서는 뷰를 사용한 실행 계획과 직접 쿼리를 사용한 실행 계획을 비교 분석하는 것이 바람직하다. 데이터베이스의 실행 계획 분석 도구를 사용하여 병목 현상을 식별하고, 필요시 뷰를 리팩토링하거나 인덱스 추가를 고려해야 한다.

6. 인덱스의 생성과 관리

인덱스는 CREATE INDEX 문을 사용하여 생성한다. 기본 구문은 CREATE INDEX 인덱스_이름 ON 테이블_이름 (컬럼1, 컬럼2, ...)이다. 인덱스를 생성할 때는 정렬 순서(ASC, DESC), 고유성(UNIQUE), 필터 조건(WHERE) 등을 추가로 지정할 수 있다. 인덱스 관리는 생성 이후의 유지보수를 포함하며, 데이터의 삽입, 갱신, 삭제가 빈번하게 일어나면 인덱스 조각화가 발생하여 성능이 저하될 수 있다. 따라서 주기적인 인덱스 재구성(REBUILD) 또는 재구축(REORGANIZE) 작업이 필요하다.

인덱스 튜닝과 최적화는 쿼리 성능 향상의 핵심 과정이다. 효과적인 튜닝을 위해선 먼저 실행 계획을 분석하여 인덱스 스캔이 발생하는지, 아니면 비효율적인 풀 테이블 스캔이 발생하는지 확인해야 한다. 자주 사용되는 조인 조건이나 WHERE 절의 필터 컬럼에 인덱스를 생성하는 것이 일반적이다. 또한, 여러 컬럼을 포함하는 복합 인덱스를 생성할 때는 컬럼의 순서가 매우 중요하며, 카디널리티가 높은 컬럼을 앞에 두는 것이 효율적이다. 데이터베이스 시스템이 제공하는 성능 모니터링 도구를 활용하여 사용 빈도가 낮거나 중복된 인덱스를 식별하고 제거하는 작업도 최적화의 일환이다.

인덱스 오용은 오히려 시스템 성능과 저장 공간에 부정적인 영향을 미친다. 첫 번째 주의점은 불필요한 인덱스의 과다 생성이다. 모든 컬럼에 인덱스를 생성하면 데이터 변경 작업(INSERT, UPDATE, DELETE) 시마다 모든 인덱스를 갱신해야 하므로 쓰기 성능이 현저히 떨어진다. 두 번째는 선택도가 낮은 컬럼에 인덱스를 생성하는 경우이다. 예를 들어, '성별'과 같이 값의 종류가 매우 적은 컬럼은 인덱스의 효율이 극히 낮다. 세 번째는 작은 테이블에 인덱스를 생성하는 것이다. 테이블이 매우 작으면 인덱스를 탐색하는 오버헤드가 직접 테이블을 스캔하는 것보다 더 클 수 있다. 마지막으로, 인덱스가 존재하더라도 인덱스 컬럼을 가공하는 함수를 사용하거나 와일드카드로 시작하는 LIKE 연산자를 사용하면 인덱스를 제대로 활용하지 못할 수 있다.

6.1. 생성 구문 (CREATE INDEX)

인덱스를 생성하는 기본 구문은 CREATE INDEX 문을 사용한다. 일반적인 형식은 다음과 같다.

```sql

CREATE [UNIQUE] INDEX 인덱스_이름

ON 테이블_이름 (컬럼1 [ASC|DESC], 컬럼2, ...)

[USING 인덱스_유형]

[WHERE 조건];

```

  • UNIQUE: 선택적 키워드로, 지정된 컬럼 조합의 값이 테이블 내에서 고유하도록 보장하는 고유 인덱스를 생성한다.

  • 인덱스_이름: 생성할 인덱스의 이름을 지정한다. 동일한 스키마 내에서 고유해야 한다.

  • ON 테이블_이름 (컬럼, ...): 인덱스를 생성할 대상 테이블과 하나 이상의 컬럼을 지정한다. 여러 컬럼을 지정하면 복합 인덱스가 생성된다. 각 컬럼 뒤에 ASC(오름차순, 기본값) 또는 DESC(내림차순)를 지정하여 정렬 방식을 정의할 수 있다.

  • USING 인덱스_유형: 사용할 인덱스 구조를 명시적으로 지정한다[3].

  • WHERE 조건: 선택적 절로, 특정 조건을 만족하는 행만 인덱스에 포함시키는 부분 인덱스를 생성할 수 있다.

다음은 employees 테이블의 last_name 컬럼에 비클러스터형 인덱스를 생성하는 기본 예시이다.

```sql

CREATE INDEX idx_lastname ON employees (last_name);

```

복합 인덱스와 고유 인덱스를 생성하는 예시는 다음과 같다.

```sql

-- department_id와 salary 컬럼에 대한 복합 인덱스

CREATE INDEX idx_dept_salary ON employees (department_id, salary DESC);

-- email 컬럼에 대한 고유 인덱스

CREATE UNIQUE INDEX idx_unique_email ON employees (email);

```

구문은 데이터베이스 관리 시스템별로 차이가 있다. 예를 들어, 오라클에서는 USING 절 대신 인덱스 유형을 생성 시 다른 파라미터로 지정하며, SQL Server에서는 INCLUDE 절을 사용하여 인덱스 키가 아닌 추가 컬럼을 리프 수준에 포함시킬 수 있다. PostgreSQL은 CONCURRENTLY 옵션으로 인덱스 생성 중 테이블 잠금을 최소화할 수 있다.

6.2. 인덱스 튜닝과 최적화

인덱스 튜닝은 데이터베이스 성능을 최적화하는 핵심 과정이다. 이는 단순히 인덱스를 추가하는 것을 넘어, 기존 인덱스의 효율성을 분석하고 불필요한 인덱스를 제거하며, 쿼리 패턴에 맞는 최적의 인덱스 전략을 수립하는 것을 포함한다. 성능 모니터링 도구를 통해 높은 디스크 I/O나 CPU 사용률을 유발하는 쿼리를 식별한 후, 해당 쿼리의 실행 계획을 분석하여 인덱스 개선 포인트를 찾는다.

인덱스 최적화를 위한 주요 원칙은 다음과 같다. 첫째, 선택도가 높은 컬럼, 즉 고유한 값이 많은 컬럼에 인덱스를 생성하는 것이 효율적이다. 둘째, 자주 사용되는 WHERE 절, JOIN 조건, ORDER BY 및 GROUP BY 절의 컬럼을 우선적으로 고려한다. 셋째, 하나의 인덱스에 여러 컬럼을 포함하는 복합 인덱스를 생성할 때는 컬럼의 순서가 중요하다. 범위 검색에 사용되는 컬럼은 마지막에 위치시키는 것이 일반적이다.

최적화 작업

주요 내용

고려 사항

인덱스 분석

사용 빈도가 낮거나 중복된 인덱스 식별

시스템 뷰(예: sys.dm_db_index_usage_stats)를 활용

인덱스 재구성/재생성

인덱스 단편화 제거로 성능 회복

REORGANIZE는 온라인 작업, REBUILD는 더 강력하지만 부하가 큼

커버링 인덱스 적용

쿼리가 필요한 모든 데이터를 인덱스에서만 접근하도록 설계

포함 컬럼(INCLUDE)을 활용하여 테이블 접근 제거

통계 업데이트

쿼리 옵티마이저가 정확한 실행 계획을 수립하도록 최신 통계 유지

자동 업데이트가 꺼져 있다면 주기적으로 UPDATE STATISTICS 실행

인덱스 튜닝은 지속적인 과정이다. 애플리케이션의 쿼리 패턴이 변경되거나 데이터 양과 분포가 변하면 기존 인덱스 전략도 재평가되어야 한다. 과도한 인덱스는 INSERT, UPDATE, DELETE 작업의 성능을 저하시키고 저장 공간을 낭비하므로, 읽기 성능 향상과 쓰기 성능 저하 사이의 균형을 유지하는 것이 중요하다.

6.3. 인덱스 오용과 주의점

인덱스는 검색 성능을 향상시키지만, 잘못 사용하면 오히려 시스템 전체 성능을 저하시키고 불필요한 자원을 낭비할 수 있다. 가장 흔한 오용 사례는 과도한 인덱스 생성이다. 각 인덱스는 데이터베이스 저장 공간을 차지하며, 데이터가 추가, 수정, 삭제될 때마다 관련 인덱스도 함께 갱신되어야 한다. 이로 인해 DML 작업의 속도가 현저히 느려질 수 있다. 특히 작은 규모의 테이블이나 자주 갱신되는 테이블에 너무 많은 인덱스를 생성하는 것은 비효율적이다.

잘못된 컬럼 선택도 주요 주의점이다. 카디널리티가 낮은 컬럼, 예를 들어 '성별'이나 '상태'처럼 중복도가 높은 컬럼에 단독 인덱스를 생성하면 검색 효율이 매우 낮다. 또한, 인덱스의 순서도 중요하다. 다중 컬럼 인덱스를 생성할 때는 쿼리의 WHERE 절 조건 빈도와 순서를 고려하여 컬럼 순서를 결정해야 한다. 첫 번째 컬럼을 제외한 나머지 컬럼만으로는 효율적인 인덱스 검색이 이루어지지 않을 수 있다.

인덱스 관리 부주의로 인한 성능 문제도 발생한다. 데이터가 자주 삽입되고 삭제되면 인덱스 단편화가 발생하여 검색 효율이 떨어질 수 있다. 따라서 주기적인 인덱스 재구성이나 재생성이 필요하다. 또한, 쿼리 작성 시 인덱스를 사용하지 못하도록 하는 패턴을 피해야 한다. 인덱스된 컬럼에 함수를 적용하거나 NULL 값을 과도하게 사용하는 경우, 옵티마이저가 인덱스를 사용하지 않고 전체 테이블 스캔을 수행할 수 있다.

주의점

설명

발생 가능한 문제

과도한 인덱스

필요 이상으로 많은 인덱스를 생성함.

DML 작업(INSERT, UPDATE, DELETE) 성능 저하, 저장 공간 낭비.

잘못된 컬럼 선택

카디널리티가 낮거나 자주 수정되는 컬럼에 인덱스 생성.

검색 효율 미비, 갱신 오버헤드만 증가.

인덱스 단편화

데이터의 빈번한 삽입/삭제로 인덱스 구조가 비효율적으로 변함.

디스크 I/O 증가, 쿼리 처리 속도 저하.

인덱스 무력화 패턴

쿼리에서 인덱스 컬럼에 함수를 사용하거나 부정형 비교(!=, NOT IN)를 남용.

옵티마이저가 인덱스를 사용하지 못하고 전체 테이블 스캔 발생.

따라서 인덱스 설계는 신중한 분석을 바탕으로 해야 한다. 실제 실행되는 쿼리 패턴을 분석하고, 데이터 분포를 이해한 후, 성능 모니터링을 통해 지속적으로 최적화하는 과정이 필수적이다.

7. 인덱싱된 뷰

인덱싱된 뷰는 뷰(View)에 클러스터형 인덱스를 생성하여 물리적으로 데이터를 저장하는 특수한 뷰이다. 일반 뷰가 실행 시점에 쿼리를 재구성하는 가상 테이블인 반면, 인덱싱된 뷰는 인덱스 생성과 함께 결과 집합이 데이터베이스에 물리적으로 저장된다. 이는 복잡한 조인이나 집계 연산의 결과를 미리 계산해 저장함으로써, 해당 뷰를 조회할 때 성능을 극적으로 향상시키는 데 목적이 있다.

인덱싱된 뷰를 생성하기 위해서는 몇 가지 엄격한 제약 조건을 충족해야 한다. 뷰 정의는 결정적 함수만 사용해야 하며, INNER JOIN만 사용하는 등의 제한이 있다. 또한, 스키마 바인딩 옵션을 사용하여 뷰 정의에 참여하는 기본 테이블의 스키마가 변경되지 않도록 고정해야 한다. 생성은 CREATE VIEW 문으로 뷰를 정의한 후, CREATE UNIQUE CLUSTERED INDEX 문을 사용하여 고유 클러스터형 인덱스를 뷰에 생성하는 방식으로 이루어진다.

특성

일반 뷰

인덱싱된 뷰

데이터 저장

저장하지 않음 (가상)

클러스터형 인덱스로 물리적 저장

성능

기본 테이블 쿼리 성능에 의존

조회 성능이 매우 빠름

오버헤드

낮음 (저장 공간 사용 안 함)

높음 (저장 공간 사용, 데이터 변경 시 유지 관리 비용 발생)

주요 목적

보안, 쿼리 단순화

복잡한 조회 쿼리의 성능 최적화

인덱싱된 뷰는 데이터 변경(INSERT, UPDATE, DELETE)이 빈번하지 않지만, 읽기 작업이 매우 많고 복잡한 조인 또는 집계 함수를 사용하는 보고서용 쿼리에서 가장 효과적이다. 기본 테이블의 데이터가 변경될 때마다 인덱싱된 뷰의 저장된 데이터도 함께 갱신되어야 하므로, 쓰기 작업에 대한 오버헤드가 발생한다는 점을 고려하여 신중하게 도입해야 한다.

7.1. 개념과 특성

인덱싱된 뷰는 물리화된 뷰 또는 구체화된 뷰라고도 불린다. 일반적인 뷰는 쿼리 실행 시점에 정의된 SELECT 문을 기반으로 결과를 동적으로 생성하는 가상 테이블이다. 반면, 인덱싱된 뷰는 뷰의 정의에 따라 쿼리 결과를 미리 계산하고, 그 결과 집합을 데이터베이스에 물리적으로 저장하는 특수한 형태의 뷰이다. 이 저장된 데이터에는 클러스터형 인덱스가 적용되어 물리적인 저장 순서가 보장되며, 빠른 데이터 접근이 가능해진다.

인덱싱된 뷰의 주요 특성은 데이터의 사전 계산과 물리적 저장에 있다. 기본 테이블의 데이터가 변경될 때마다, 데이터베이스 시스템은 인덱싱된 뷰에 저장된 결과 데이터를 자동으로 갱신하여 일관성을 유지한다. 이는 특히 조인이나 집계 함수(SUM, COUNT, AVG 등)가 포함된 복잡한 쿼리의 성능을 극적으로 향상시킬 수 있다. 사용자가 해당 뷰를 조회할 때마다 매번 기본 테이블들을 조인하고 집계를 계산할 필요 없이, 이미 저장된 결과를 바로 반환할 수 있기 때문이다.

인덱싱된 뷰를 생성하기 위해서는 몇 가지 엄격한 제약 조건을 만족해야 한다. 일반적으로 ANSI_NULLS와 QUOTED_IDENTIFIER 옵션이 ON 상태여야 하며, 뷰 정의는 결정적이어야 한다[4]. 또한 OUTER JOIN의 사용이 제한되거나 특정 데이터베이스 관리 시스템마다 다른 규칙이 적용될 수 있다. 가장 중요한 선행 조건은 뷰에 대해 고유한 클러스터형 인덱스를 먼저 생성해야 한다는 점이다. 이 클러스터형 인덱스가 물리적 저장을 가능하게 하는 기반이 된다.

특성

일반 뷰

인덱싱된 뷰

데이터 저장

저장하지 않음 (가상)

물리적으로 저장함

성능

기본 테이블 조회 속도에 의존

사전 계산된 데이터로 매우 빠름

갱신 오버헤드

없음

기본 테이블 변경 시 갱신 비용 발생

주요 용도

논리적 데이터 추상화, 보안

복잡 조인/집계 쿼리의 성능 최적화

따라서 인덱싱된 뷰는 읽기 작업이 매우 빈번하고, 데이터의 실시간 갱신보다는 조회 성능이 더 중요한 보고서 생성이나 분석용 데이터베이스에서 효과적으로 활용된다.

7.2. 생성 방법 및 제약 조건

인덱싱된 뷰를 생성하기 위해서는 몇 가지 엄격한 제약 조건을 만족해야 한다. 먼저, 뷰는 SCHEMABINDING 옵션을 사용하여 생성되어야 하며, 이는 뷰 정의에 참여하는 기본 테이블의 스키마를 변경하지 못하도록 바인딩한다. 또한, 뷰 정의는 단일 SELECT 문으로만 구성되어야 하며, 집계 함수를 사용하지 않는 경우 COUNT_BIG(*)를 포함해야 하는 등의 규칙이 적용된다[5].

생성 방법은 일반 뷰를 만든 후에 고유 클러스터형 인덱스를 생성하는 두 단계로 이루어진다. 첫 번째 단계에서는 WITH SCHEMABINDING을 포함한 CREATE VIEW 문을 사용하여 뷰를 정의한다. 두 번째 단계에서는 이 뷰에 대해 CREATE UNIQUE CLUSTERED INDEX 문을 실행하여 물리적인 인덱스를 구축한다. 이 인덱스가 생성된 후에는 필요에 따라 추가적인 비클러스터형 인덱스를 생성할 수 있다.

주요 제약 조건은 다음과 같다.

제약 사항

설명

SCHEMABINDING 필수

뷰 정의에 사용된 기본 테이블의 구조를 변경할 수 없게 한다.

결정적 함수만 사용

뷰 정의에는 GETDATE() 같은 비결정적 함수를 사용할 수 없다.

특정 구문 제한

OUTER JOIN, UNION, 하위 쿼리, TOP, DISTINCT(집계 시 제외) 등의 사용이 제한된다.

데이터베이스별 차이

옵티미스트 잠금 수준 설정 등 구현체별 고유 조건이 존재한다.

이러한 제약 조건은 뷰의 결과 집합이 명확하고 안정적이어야 인덱스로 물리적으로 구현될 수 있기 때문에 필요하다. 조건을 위반하면 인덱스 생성이 실패하거나, 나중에 기본 테이블의 스키마를 변경할 수 없게 된다.

7.3. 성능 향상 효과

인덱싱된 뷰는 물리적 뷰로 구현되어 쿼리 성능을 극적으로 향상시킬 수 있다. 기본적인 뷰가 단순한 쿼리 재사용성을 제공하는 반면, 인덱싱된 뷰는 클러스터형 인덱스를 통해 데이터 자체를 물리적으로 저장한다. 이는 복잡한 조인이나 집계 연산 결과를 미리 계산하여 저장해두는 것과 같아, 해당 뷰를 조회할 때마다 연산을 다시 수행할 필요가 없어진다.

주요 성능 향상 효과는 다음과 같다. 첫째, 자주 실행되는 복잡한 조인이나 집계 함수(SUM, AVG, COUNT 등)를 포함하는 쿼리의 실행 속도가 크게 개선된다. 둘째, 기본 테이블의 데이터가 변경되더라도 인덱싱된 뷰는 자동으로 유지 관리되므로, 애플리케이션 로직을 변경하지 않고도 일관된 성능 이점을 얻을 수 있다. 셋째, 특히 데이터 웨어하우스나 보고 시스템에서 대량의 데이터를 읽어야 하는 OLAP 쿼리 성능에 매우 효과적이다.

성능 이점

설명

쿼리 실행 시간 단축

조인 및 집계 결과가 물리적으로 저장되어, 실행 시 계산 오버헤드가 제거된다.

기본 테이블 부하 감소

자주 접근하는 복잡한 쿼리가 인덱싱된 뷰를 통해 처리되어 기본 테이블의 직접적인 읽기 부하를 줄인다.

실행 계획 최적화

쿼리 옵티마이저가 인덱싱된 뷰를 활용하여 더 효율적인 실행 계획을 수립할 수 있다.

그러나 성능 향상은 데이터 변경 작업에는 비용으로 작용한다. 기본 테이블의 데이터가 추가, 수정, 삭제될 때마다 관련된 인덱싱된 뷰도 함께 갱신되어야 하므로, 쓰기 작업의 오버헤드가 증가한다. 따라서 읽기 작업이 압도적으로 많고 데이터 변경이 빈번하지 않은 환경에서 가장 큰 효과를 발휘한다. 시스템 설계 시 이 트레이드오프를 신중히 고려해야 한다.

8. 데이터베이스별 구현 차이

주요 관계형 데이터베이스 관리 시스템마다 뷰와 인덱스의 구현과 기능에 미묘한 차이가 존재한다. 이러한 차이는 각 DBMS의 설계 철학, 스토리지 엔진, 그리고 최적화 전략에 기인한다.

기능 / DBMS

SQL Server

Oracle Database

MySQL

PostgreSQL

인덱싱된 뷰

물리화된 뷰로 지원. WITH SCHEMABINDING 등 제약 조건이 많음.

물리화된 뷰(Materialized View)로 지원. 직접 인덱스 생성 가능하며 주로 데이터 웨어하우스에서 사용됨.

제한적 지원. InnoDB 스토리지 엔진 기반의 물리화된 뷰는 공식적으로 지원하지 않으나, 스토어드 프로시저나 트리거로 유사 구현 가능.

물리화된 뷰 완전 지원. CREATE MATERIALIZED VIEW 구문을 사용하며 REFRESH 명령으로 데이터 갱신함.

인덱스 유형

클러스터형, 비클러스터형, 커버링 인덱스, 필터링된 인덱스(WHERE 조건), 공간 인덱스 등을 지원.

B-Tree, 비트맵 인덱스, 함수 기반 인덱스, 도메인 인덱스 등 풍부한 유형을 제공.

주로 B-Tree(기본), 해시 인덱스(MEMORY 엔진), 풀텍스트 인덱스, 공간 인덱스(R-Tree)를 지원. InnoDB는 클러스터형 인덱스 구조를 사용.

B-Tree(기본), 해시, GIN(Generalized Inverted Index), GiST(Generalized Search Tree), SP-GiST, BRIN 등 매우 다양한 인덱스 유형과 접근 방식을 지원.

뷰 업데이트

단순 뷰(한 테이블, 키 보존)에 대해 INSERT/UPDATE/DELETE 가능. 인덱싱된 뷰는 제한적.

INSTEAD OF 트리거를 사용하여 복잡한 뷰에 대한 DML 연산을 구현할 수 있음.

일부 제한 사항이 있지만, 단일 기본 테이블에 기반한 간단한 뷰는 업데이트 가능함.

INSTEAD OF 트리거를 사용하여 업데이트 가능한 뷰를 생성할 수 있음. 규칙 시스템을 통한 업데이트도 옵션으로 제공됨.

부분 인덱스

필터링된 인덱스라는 이름으로 지원. WHERE 절을 사용하여 인덱싱할 행의 부분 집합을 정의함.

기본적으로 지원하지 않으나, 함수 기반 인덱스나 가상 컬럼을 활용하여 유사한 효과를 낼 수 있음.

MySQL 8.0부터 함수형 인덱스를 지원하며, 이를 이용해 조건부 인덱싱을 구현할 수 있음.

부분 인덱스를 완벽 지원. CREATE INDEX ... WHERE 구문을 사용하여 특정 조건을 만족하는 행만 인덱싱함.

이러한 구현 차이로 인해, 특정 DBMS에 최적화된 스키마 설계나 쿼리 튜닝 기법이 다른 시스템에서는 동일한 성능을 보장하지 않을 수 있다. 예를 들어, Oracle의 비트맵 인덱스는 데이터 웨어하우스 환경에서 우수한 성능을 보이지만, OLTP 환경에서는 부적합할 수 있다. 반면, PostgreSQL의 GIN 인덱스는 배열이나 JSONB 데이터와 같은 비정형 데이터를 효율적으로 검색하는 데 특화되어 있다. 따라서 데이터베이스 애플리케이션을 개발하거나 마이그레이션할 때는 이러한 플랫폼별 특성을 반드시 고려해야 한다.

8.1. SQL Server, Oracle, MySQL, PostgreSQL 비교

주요 관계형 데이터베이스 관리 시스템마다 뷰와 인덱스의 구현과 기능에 미묘한 차이가 존재한다. 이러한 차이는 구문, 지원하는 기능, 성능 특성에 영향을 미친다.

기능 / 특성

Microsoft SQL Server

[[오라클 (데이터베이스)

Oracle]]

MySQL

PostgreSQL

인덱싱된 뷰

물리화된 뷰(Materialized View)로 지원. CREATE UNIQUE CLUSTERED INDEX로 생성한다.

물리화된 뷰(Materialized View)로 지원. CREATE MATERIALIZED VIEW 문을 사용한다.

공식적으로 인덱싱된 뷰를 지원하지 않는다. 유사한 목적으로 생성된 테이블을 사용하거나, 일부 스토리지 엔진의 제한된 기능을 활용할 수 있다.

물리화된 뷰(Materialized View)로 지원. CREATE MATERIALIZED VIEW 문을 사용하며, REFRESH MATERIALIZED VIEW로 데이터를 갱신한다.

표준 뷰 업데이트

INSTEAD OF 트리거를 사용하여 업데이트 가능한 뷰를 구현할 수 있다. 특정 조건 하에서 직접 UPDATE가 가능한 경우도 있다.

일반적으로 업데이트 가능하다. 단일 테이블에 기반하고 키를 보존하는 등 규칙을 충족해야 한다. INSTEAD OF 트리거도 사용 가능하다.

업데이트 가능한 뷰를 지원하지만, [[조인 (SQL)

JOIN]], 집계 함수, DISTINCT, GROUP BY 등을 포함하는 복잡한 뷰는 업데이트가 제한된다.

업데이트 가능한 뷰를 지원한다. 규칙 시스템(CREATE RULE)이나 INSTEAD OF 트리거를 사용하여 복잡한 뷰의 수정을 처리할 수 있다.

인덱스 유형

클러스터형, 비클러스터형, 필터링된 인덱스, 컬럼스토어 인덱스 등을 지원한다.

B-Tree, 비트맵, 함수 기반 인덱스, 도메인 인덱스 등을 지원한다.

스토리지 엔진에 의존한다. InnoDB는 B-Tree를, MEMORY 엔진은 해시 인덱스를 주로 사용한다. 최신 버전에서는 함수형 인덱스도 지원한다.

B-Tree, 해시, GIST, GIN, BRIN 등 다양한 인덱스 유형을 지원하여 표준 및 전문 검색에 최적화되어 있다.

부분 인덱스

필터링된 인덱스(Filtered Index)라는 이름으로 지원한다. WHERE 절을 사용하여 인덱싱할 행의 부분 집합을 정의한다.

기본적으로 지원하지 않는다. 함수 기반 인덱스나 파티셔닝으로 유사 효과를 낼 수 있다.

지원하지 않는다.

부분 인덱스(Partial Index)를 완벽하게 지원한다. CREATE INDEX ... WHERE 조건을 사용하여 특정 조건을 만족하는 행만 인덱싱한다.

이러한 차이점은 각 DBMS의 설계 철학과 진화 경로를 반영한다. 예를 들어, PostgreSQL은 확장성과 표준 준수에 중점을 두어 다양한 고급 인덱스 유형과 부분 인덱스를 제공하는 반면, SQL Server는 엔터프라이즈 환경의 통합 관리와 성능에 초점을 맞춘다. Oracle은 대규모 트랜잭션 처리와 데이터 웨어하우징을 모두 고려한 기능 세트를 갖추고 있다. MySQL은 단순성과 웹 응용 프로그램에의 적합성을 강점으로 하지만, 최근 버전에서는 기능이 빠르게 확장되고 있다. 데이터베이스를 선택하거나 애플리케이션을 이식할 때는 이러한 구현 차이를 반드시 고려해야 한다.

9. 관련 문서

  • Oracle - 뷰(View) 개요

  • Microsoft SQL Server - 뷰 생성

  • MySQL - 뷰 생성 및 사용

  • PostgreSQL - 뷰(Views)

  • Oracle - 인덱스(Index) 기본

  • Microsoft SQL Server - 인덱스 생성 및 수정

  • MySQL - 인덱스 사용 방법

  • IBM Db2 - 뷰 및 인덱스 개념

  • SQLite - 인덱스에 대한 설명

  • MongoDB - 인덱스(Indexes)

리비전 정보

버전r1
수정일2026.02.14 21:42
편집자unisquads
편집 요약AI 자동 생성