DB Index

hyeo71·2025년 10월 21일
0

CS

목록 보기
8/8

DB Index

데이터베이스 테이블의 검색(SELECT) 속도를 획기적으로 향상시켜주는 자료구조

책의 목차에 비유한 인덱스 설명

  • 인덱스가 없을 때
    책에서 특정 단어를 찾으려면 첫 페이지부터 끝까지 모든 페이지(Full Scan)를 확인
    -> 데이터베이스에서는 테이블의 모든 행을 확인
    -> 느림

  • 인덱스가 있을 때
    책의 목차나 색인을 통해 원하는 내용이 몇 페이지에 있는지 확인하고, 그 페이지로 바로 이동
    -> 데이터베이스에서는 인덱스에서 데이터의 물리적 주소를 찾아 바로 접근
    -> 빠름


Index의 자료구조

A. B+Tree(B-Plus Tree) - 가장 일반적 & 표준

  • 특징
    데이터를 정렬된 상태로 유지
    리프 노드에만 실제 데이터를 저장하거나 데이터의 포인터를 저장하며, 이 리프 노드들은 링크드 리스트로 연결

  • 사용 목적
    범위 검색(<, >, BETWEEN) 및 정렬(ORDER BY)에 매우 효율적이며, 대부분의 관계형 데이터베이스(RDB) 인덱스의 기본값

B. Hash Index(해시 인덱스)

  • 특징
    키 값에 해시 함수를 적용하여 해시 테이블 형태로 저장
    데이터가 정렬되어 있지 않음

  • 사용 목적
    동등 비교 검색(=)시 주소를 O(1)가장 빠르게 검색

  • 제한
    데이터가 정렬되어 있지 않아 범위 검색이나 정렬에는 사용 불가(DBMS에 따라 지원 여부 및 활용 범위가 다름)


Index의 유형

A. 클러스터드 인덱스(Clustered Index)

  • 역할
    인덱스의 리프 노드가 실제 데이터 행 자체
    데이터의 물리적인 저장 순서가 이 인덱스 순서대로 정렬

  • 개수
    테이블당 오직 1개만 생성 가능, 주로 Primary Key(기본 키) 지정 시 자동으로 생성

  • 조회
    인덱스 검색 후 데이터에 바로 접근(1단계) -> 가장 빠른 조회 제공

B. 세컨더리 인덱스(Secondary Index, 보조 인덱스)

  • 역할
    데이터와 별도로 생성
    리프 노드에는 컬럼 값과 해당 데이터의 클러스터드 키 값(또는 물리적 주소)만 저장

  • 개수
    테이블당 여러 개 생성 가능

  • 조회
    세컨더리 인덱스 검색 -> 클러스터드 키 획득 -> 클러스터드 인덱스를 통해 테이블 접근(2단계)이 필요


장단점 및 생성 기준

장단점

장점

  • 조회
    검색(SELECT) 속도 및 시스템 전반의 성능 향상

단점

  • 저장/변경
    추가 저장 공간 필요
    데이터 변경(CUD) 시 성능 저하(인덱스 갱신 필요)

생성 기준

  1. 규모가 큰 테이블: 데이터 양이 적으면 Full Scan이 더 빠를 수 있음
  2. WHERE, ORDER BY, JOIN 절에 자주 사용되는 컬럼
  3. 카디널리티(Cardinality)가 높은 컬럼: 데이터의 중복도가 낮은 컬럼일수록 효율적(ex. ID, 주민번호, 이메일)

생성 및 활용

컬럼인덱스 유형
member_idINTPrimary Key(클러스터드 인덱스 자동 생성)
memeber_nameVARCHAR
emailVARCHAR
join_dateDATE

생성

-- (기본값) B+Tree 세컨더리 인덱스 생성
CREATE INDEX idx_members_join_date ON members (join_date); 

-- 특정 자료구조 명시 (DBMS가 지원하는 경우)
CREATE INDEX idx_members_email ON members (email) USING HASH;

커버링 인덱스를 활용한 최적화

쿼리가 요구하는 모든 컬럼이 인덱스에 포함되도록 인덱스를 설계하여, 실제 테이블 접근(Table Fetch) 없이 인덱스만으로 조회를 완료

-- 복합 인덱스 생성 (이름 검색 후 가입일 조회에 사용)
CREATE INDEX idx_members_name_date ON members (member_name, join_date);

-- 쿼리: 이름으로 검색하고 가입일만 조회
-- 이 경우, 인덱스(member_name, join_date)만 읽어 결과를 반환 (최적의 성능)
EXPLAIN SELECT member_name, join_date FROM members 
WHERE member_name = '홍길동';

옵티마이저의 역할

인덱스를 만들더라도, 데이터베이스 내부의 옵티마이저(Optimizer)가 쿼리 실행 시 비용을 계산하여 인덱스 스캔보다 Full Scan이 빠르다고 판단하면 인덱스를 사용하지 않을 수 있음 (ex. 조회하려는 데이터 비율이 전체의 10~20%를 초과할 때)

0개의 댓글