데이터베이스 인덱스

기술노트

데이터베이스 인덱스 (Database Index)

데이터베이스 인덱스(Index)는 테이블의 데이터 검색 속도를 향상시키기 위해 사용하는 자료구조입니다. 책의 맨 뒤에 있는 '찾아보기'와 같이, 특정 데이터를 찾기 위해 전체 테이블을 스캔하는(Full Table Scan) 대신, 인덱스를 통해 데이터가 저장된 위치를 빠르게 찾아갈 수 있도록 돕습니다.


📈 인덱스의 장점과 단점

  • 장점 (Advantages)

> * 검색 속도 향상 : `SELECT` 쿼리의 `WHERE` 절이나 `JOIN` 작업의 성능을 극적으로 향상시킵니다. > * 정렬 속도 향상 : `ORDER BY` 절에 대한 정렬 과정을 피할 수 있어(인덱스는 이미 정렬되어 있으므로) 성능이 향상됩니다. > * 고유성 보장 : `UNIQUE` 인덱스를 통해 특정 컬럼 값의 유일성을 강제할 수 있습니다.

  • 단점 (Disadvantages)

> * 저장 공간 차지 : 인덱스는 테이블 데이터와 별도의 저장 공간을 필요로 합니다. (일반적으로 테이블 크기의 약 10% 내외) > * DML 성능 저하 : `INSERT`, `UPDATE`, `DELETE` 작업 시, 데이터 변경뿐만 아니라 인덱스 정보도 함께 수정해야 하므로 성능이 저하됩니다. > * 잘못된 사용 시 비효율 : 인덱스 설계가 잘못되거나, 데이터 분포도(Cardinality)가 낮은 컬럼에 인덱스를 사용하면 오히려 성능이 악화될 수 있습니다.


🌳 대표적인 인덱스 자료구조: B-Tree

대부분의 관계형 데이터베이스(RDBMS)는 인덱스 자료구조로 B-Tree(Balanced Tree) 또는 이를 개선한 B+Tree를 사용합니다.

  • B-Tree 구조 : 루트(Root), 브랜치(Branch), 리프(Leaf) 노드로 구성된 균형 잡힌 트리입니다. 항상 균형을 유지하여, 어떤 값을 찾더라도 유사한 탐색 시간(O(log n))을 보장합니다.
  • B+Tree 특징 : B-Tree와 달리, 리프 노드만 실제 데이터의 주소(포인터)를 가지고 있으며, 리프 노드끼리는 연결 리스트(Linked List)로 연결되어 있어 범위 탐색(Range Scan)에 더욱 효율적입니다. (예: `WHERE age BETWEEN 20 AND 30`)
  • 효율적인 이유 : 데이터베이스는 디스크에 데이터를 저장하므로, 한 번의 디스크 I/O로 많은 데이터를 읽을 수 있도록 하나의 노드에 여러 개의 데이터를 저장하는 B-Tree 계열의 자료구조가 효율적입니다.

💡 개발자 핵심 Point

  • 인덱스 설계 원칙

> * `WHERE` 절에서 자주 사용되는 컬럼에 인덱스를 생성합니다. > * 데이터의 분포도(Cardinality), 즉 고유한 값의 종류가 많은 컬럼(e.g., 이메일)에 생성하는 것이 효율적입니다. '성별'처럼 종류가 적은 컬럼은 비효율적입니다. > * `JOIN`에 자주 사용되는 외래 키(Foreign Key) 컬럼에는 인덱스를 생성하는 것이 좋습니다. > * `SELECT`보다 `INSERT`, `UPDATE`, `DELETE` 작업이 훨씬 빈번한 테이블에는 인덱스 생성을 신중하게 고려해야 합니다.

  • 실행 계획 (Execution Plan) : 쿼리가 인덱스를 잘 사용하고 있는지 확인하려면 '실행 계획'을 분석해야 합니다. 옵티마이저가 'Full Table Scan'을 선택했다면 인덱스가 사용되지 않고 있다는 의미이므로 쿼리나 인덱스 설계를 검토해야 합니다.
  • 클러스터형 vs 비클러스터형 인덱스

> * 클러스터형(Clustered) : 테이블 당 하나만 존재하며, 데이터 자체가 인덱스와 함께 물리적으로 정렬되어 저장됩니다. (PK 생성 시 자동 생성) > * 비클러스터형(Non-Clustered) : 테이블 당 여러 개 존재 가능하며, 인덱스 페이지와 데이터 페이지가 분리되어 있습니다. (일반적인 인덱스)