인덱스(Index)의 개념과 데이터베이스에서의 역할
인덱스(Index)란 데이터베이스 테이블에서 데이터를 빠르게 검색하기 위한 자료구조입니다.
일반적으로 책의 목차나 전화번호부처럼, 특정 값을 빠르게 찾아가는 목적으로 사용됩니다. 인덱스가 없는 테이블에서 WHERE 조건으로 데이터를 조회하면, 데이터베이스는 전체 테이블을 처음부터 끝까지 확인하는 전체 테이블 스캔(Full Table Scan)을 수행하게 되어 비효율적입니다.
인덱스는 SELECT 쿼리의 속도 향상을 목적으로 하지만, INSERT, UPDATE, DELETE와 같은 DML 작업에서는 부담이 증가할 수 있으므로 신중한 설계가 필요합니다.
인덱스의 자료구조와 내부 동작 방식
인덱스는 단순한 리스트가 아니라, 검색 성능을 극대화할 수 있도록 특정한 자료구조로 구현되어 있습니다. 대표적인 자료구조는 다음과 같습니다.
B-Tree 인덱스의 구조와 작동 방식
가장 많이 사용되는 인덱스 자료구조는 B-Tree (Balanced Tree) 구조입니다.
MySQL(InnoDB), Oracle, PostgreSQL 등 대부분의 DBMS에서 기본 인덱스 구조로 사용됩니다.
- B-Tree는 각 노드가 여러 개의 자식을 가질 수 있는 균형 이진 탐색 트리(Balanced Binary Search Tree)의 일반화된 형태입니다.
- 루트 노드에서 시작하여 중간 노드를 비교해 내려가면서, 원하는 키를 로그 시간(log n)에 탐색할 수 있습니다.
- 리프 노드까지 도달하면, 해당 인덱스에 연결된 실제 데이터의 위치(ROWID 등)를 통해 테이블의 데이터를 조회합니다.
특징:
- 정렬된 상태로 유지되며, 범위 검색에 최적화되어 있습니다.
- INSERT, DELETE 시에도 트리의 균형을 유지하기 위한 재정렬이 자동으로 수행됩니다.
해시 인덱스(Hash Index)의 구조와 작동 방식
일부 DBMS(MySQL의 MEMORY 엔진 등)는 해시 테이블 기반의 인덱스를 지원합니다.
- 키 값을 해시 함수로 계산하여, 해당 해시값이 저장된 슬롯에 바로 접근합니다.
- 매우 빠른 동등 비교(equal = 검색)에 특화되어 있으며, 범위 검색에는 부적합합니다.
주의:
- 대부분의 범용 DBMS에서는 범위 검색, 정렬 등을 지원하기 위해 B-Tree가 기본값입니다.
- 해시 인덱스는 특별한 상황에서만 사용됩니다.
비트맵 인덱스(Bitmap Index)의 구조와 용도
비트맵 인덱스는 주로 카디널리티(고유값의 수)가 낮은 열에 사용됩니다.
예: 성별(Gender), 상태(Status), 지역코드(Region Code) 등.
- 각 가능한 값에 대해 비트를 할당하고, 행의 존재 여부를 0 또는 1로 표현합니다.
- OR, AND, NOT 연산을 통해 복잡한 조건 조합에도 빠르게 대응할 수 있습니다.
- 다만, 병행 삽입/수정에는 약해 대부분 **데이터 분석용 시스템(DSS, DW)**에서 사용됩니다.
인덱스가 효율적인 이유에 대한 기술적 분석
인덱스가 성능 향상에 기여하는 이유는 다음과 같은 검색 알고리즘 최적화와 디스크 I/O 감소에 있습니다.
- 접근 시간의 대폭 감소
- B-Tree를 사용하는 경우, 전체 테이블이 수백만 행이어도 O(log n) 시간 안에 원하는 값을 탐색할 수 있습니다.
- 디스크 I/O 감소
- 인덱스만으로 필요한 데이터를 얻을 수 있는 **커버링 인덱스(Covering Index)**를 사용할 경우, 실제 테이블(데이터 페이지)에 접근하지 않아도 됩니다.
- 정렬 비용 절감
- ORDER BY 절에 사용되는 컬럼이 인덱스에 포함되어 있다면, 정렬 없이 그대로 결과를 출력할 수 있습니다.
- 범위 조건 최적화
- BETWEEN, >, <, IN 등 범위 조건을 사용할 때, B-Tree 인덱스가 정렬된 구조이므로 효율적인 탐색이 가능합니다.
성능 최적화를 위한 인덱스 활용 기법
인덱스는 단순히 생성하는 것만으로 끝나지 않습니다. 어떻게 구성하고 어떻게 활용하는지에 따라 성능에 큰 차이가 발생합니다.
다중 컬럼 인덱스 (Composite Index)
- 하나의 인덱스에 여러 컬럼을 순서대로 포함시킵니다.
- 인덱스의 선행 컬럼부터 순서대로 조건절에 사용될 때 성능이 극대화됩니다.
- 예: INDEX(col1, col2)로 생성했을 경우, WHERE col1 = ? 또는 WHERE col1 = ? AND col2 = ?는 인덱스 사용 가능하지만, WHERE col2 = ? 단독 조건은 비효율적일 수 있습니다.
인덱스의 선택도(Selectivity) 고려
- 선택도란 특정 컬럼에서 전체 데이터 중 인덱스를 통해 얼마나 정확히 필터링할 수 있는지를 의미합니다.
- 선택도가 높을수록 인덱스 효율이 좋습니다. 즉, 고유한 값이 많은 컬럼이 인덱스에 적합합니다.
커버링 인덱스(Covering Index)
- SELECT 절의 모든 컬럼이 인덱스에 포함되어 있다면, 데이터 페이지까지 접근하지 않아도 됩니다.
- 이를 통해 디스크 I/O를 최소화할 수 있으며, 실행 계획에서도 Using index로 표시됩니다.
인덱스의 정렬 방향 지정
- MySQL에서는 ASC, DESC로 정렬 방향을 지정할 수 있으며, ORDER BY 조건과 정렬 방향이 일치해야 인덱스를 효과적으로 사용할 수 있습니다.
과도한 인덱스 생성의 문제점
- 인덱스가 많을수록 INSERT/UPDATE/DELETE 시 추가 비용이 발생합니다.
- 인덱스가 많으면 오히려 옵티마이저가 인덱스 선택에 혼란을 겪고 비효율적인 실행 계획을 생성할 수 있습니다.
- 정기적인 인덱스 재구성(REBUILD) 또는 ANALYZE가 필요할 수 있습니다.
인덱스와 옵티마이저(Optimizer)의 관계
인덱스는 단독으로 동작하지 않으며, 쿼리 옵티마이저가 어떤 인덱스를 언제 사용하는지를 판단합니다.
- 옵티마이저는 통계 정보(statistics)와 카탈로그 정보를 바탕으로, 가장 비용이 낮은 실행 계획을 선택합니다.
- 인덱스가 존재하더라도, 옵티마이저가 비용이 더 높다고 판단하면 사용하지 않을 수 있습니다.
옵터마이저에 대해 궁금하다면? 아래 클릭
옵티마이저(Optimizer)는 데이터베이스 관리 시스템(DBMS)에서 SQL 쿼리를 가장 빠르고 효율적으로 실행하기 위한 최적의 실행 계획(Execution Plan)을 선택하는 컴포넌트입니다.
옵티마이저의 개념과 역할
SQL 쿼리를 실행할 때, 같은 결과를 낼 수 있는 방법은 여러 가지가 존재합니다.
예를 들어, 테이블을 먼저 조인할 수도 있고, 특정 인덱스를 사용할 수도 있으며, 테이블을 순차적으로 스캔할 수도 있습니다.
옵티마이저는 이러한 여러 실행 경로 중에서 예상 비용(Cost)을 계산하여 가장 효율적인 실행 계획을 선택합니다. 이 과정을 쿼리 최적화(Query Optimization)라고 합니다.
옵티마이저가 수행하는 주요 작업
- 어떤 인덱스를 사용할지 결정
- 조인 순서 결정 (Nested Loop, Hash Join 등)
- 테이블 접근 방식 결정 (Index Scan, Full Table Scan 등)
- 정렬 또는 그룹화 전략 선택
옵티마이저의 유형
비용 기반 옵티마이저(Cost-Based Optimizer, CBO)
- 각 실행 계획에 대해 비용(cost)을 수치화하여 가장 저렴한 경로를 선택합니다.
- 비용은 디스크 I/O, CPU 사용량, 메모리, 예상 결과 행 수 등을 고려하여 계산됩니다.
- 대부분의 현대 DBMS는 이 방식을 채택합니다. (Oracle, PostgreSQL, MySQL(InnoDB), SQL Server 등)
규칙 기반 옵티마이저(Rule-Based Optimizer, RBO)
- 사전에 정의된 규칙(rule)에 따라 실행 계획을 결정합니다.
- 예: 인덱스가 존재하면 무조건 인덱스를 사용함
- 단순하지만 유연성이 낮고 비효율적이어서 현재는 거의 사용되지 않습니다.
요약
- 인덱스는 데이터 검색을 빠르게 하기 위한 핵심 구조이며, B-Tree, 해시, 비트맵 등의 자료구조로 구현됩니다.
- 인덱스를 사용하면 검색 성능이 극대화되지만, 잘못된 설계는 오히려 성능을 저하시키므로 주의가 필요합니다.
- 효율적인 인덱스 설계는 선택도 고려, 다중 컬럼 구성, 커버링 인덱스 활용 등을 포함합니다.
- 옵티마이저가 인덱스를 어떻게 사용하는지도 반드시 숙지하고 있어야 면접에서 깊이 있는 설명이 가능합니다.
'백엔드 공부일지 > 데이터베이스 공부일지' 카테고리의 다른 글
데이터베이스 정규화: 제1정규형부터 보이스/코드 정규형까지 (0) | 2025.05.13 |
---|---|
데이터베이스 정규화: 이상현상과 함수적 종속성까지 (0) | 2025.05.13 |
클러스터드 인덱스와 넌클러스터드 인덱스 차이 (0) | 2025.05.12 |
데이터베이스 트랜잭션 격리수준과 이상현상 (0) | 2025.05.11 |
트랜잭션이란? 커밋, 롤백, ACID, 격리성까지 (0) | 2025.05.11 |