[CS -DB] Index 상식, JPA에서 자동생성하는 Index, Index가 많아지면 생기는 문제

2025. 2. 20. 21:55·면접 준비
728x90
반응형
SMALL

데이터베이스 인덱스(Index)란? 인덱스가 많아지면 생기는 문제

데이터베이스를 다루다 보면 '인덱스(Index)'라는 개념을 자주 접하게 된다. 인덱스는 데이터 검색 속도를 향상시키는 핵심적인 요소지만, 무분별하게 생성하면 오히려 성능 저하를 초래할 수 있다. 이번 글에서는 인덱스의 의미와 사용해야 하는 경우, 그리고 인덱스가 많아질 때 발생하는 문제까지 논리적으로 정리해 보겠다.

1. 인덱스(Index)란?

인덱스(Index)는 데이터베이스 테이블에서 특정 컬럼의 값을 빠르게 찾을 수 있도록 도와주는 자료구조이다. 책의 목차와 비슷한 역할을 하며, 특정 데이터를 검색할 때 테이블 전체를 탐색하는 것이 아니라, 인덱스를 통해 빠르게 원하는 데이터를 찾을 수 있다.

인덱스의 기본 개념과 종류

1) B-Tree (Balanced Tree) 인덱스

B-Tree 인덱스는 대부분의 관계형 데이터베이스에서 기본적으로 사용하는 인덱스 구조로, 균형 트리(Balanced Tree) 구조를 이용하여 검색 속도를 높인다. 각 노드는 정렬된 상태로 유지되며, 검색, 삽입, 삭제가 빠르게 수행된다.

https://www.geeksforgeeks.org/difference-between-b-tree-and-b-tree/

B-Tree의 주요 변형 종류:

  • B+Tree: 리프 노드에서만 실제 데이터를 저장하며, 리프 노드끼리 연결 리스트로 연결되어 있어 범위 검색 성능이 뛰어나다.
  • B*Tree: B+Tree의 변형으로, 노드 분할을 줄이기 위해 더 많은 데이터를 저장할 수 있도록 최적화된 구조이다.
  • B#Tree: 인덱스 유지 비용을 낮추기 위해 주어진 범위 내에서 최적의 균형을 유지하는 방식으로 설계되었다.

https://velog.io/@ryuhyewon/B-tree-Btree

예시:

CREATE INDEX idx_customer_id ON orders (customer_id);

이렇게 생성된 B-Tree 인덱스는 customer_id 컬럼을 기준으로 정렬된 트리 구조를 형성하며, 특정 고객의 주문 데이터를 빠르게 검색할 수 있다.

2) Hash 인덱스

해시 테이블을 기반으로 한 인덱스로, 정확한 값 매칭이 필요한 경우 유용하다. 범위 검색이 어렵고, = 연산을 통한 조회에서만 강력한 성능을 발휘한다.

예시:

CREATE INDEX idx_product_code ON products USING HASH (product_code);

이 인덱스는 product_code의 정확한 일치 검색에서만 빠른 속도를 제공한다.

B-Tree가 Hash 인덱스보다 더 많이 사용되는 이유

  1. 범위 검색 지원: B-Tree는 데이터가 정렬된 상태로 유지되므로 BETWEEN, >=, <= 같은 연산을 빠르게 수행할 수 있다. 반면, Hash 인덱스는 키-값 매칭을 위한 구조라 범위 검색이 불가능하다.
  2. ORDER BY와 GROUP BY 최적화: B-Tree는 데이터를 정렬된 상태로 유지하므로 정렬이나 그룹화 연산에서 추가적인 비용 없이 성능을 높일 수 있다.
  3. 다양한 비교 연산 지원: B-Tree는 =, <, >, LIKE 'prefix%' 같은 다양한 연산을 최적화할 수 있지만, Hash 인덱스는 = 연산에만 최적화되어 있다.
  4. 충돌 문제 없음: Hash 인덱스는 해시 충돌이 발생할 수 있어 조회 성능이 일정하지 않지만, B-Tree는 항상 일정한 성능을 보장한다.
  5. 멀티 컬럼 인덱스 가능: B-Tree는 다중 컬럼을 포함하는 복합 인덱스를 만들 수 있어 복잡한 검색 조건에서도 성능 최적화가 가능하다.

2. 인덱스를 사용해야 하는 경우

인덱스는 검색 속도를 높이는 데 유용하지만, 모든 경우에 적합한 것은 아니다. 적절한 경우에 사용해야만 성능을 최적화할 수 있다.

2.1 인덱스를 적용해야 하는 경우

  1. WHERE 절에서 특정 컬럼을 자주 조회하는 경우
    • customer_id 컬럼에 인덱스가 없으면 테이블 전체를 검색(Full Table Scan)해야 하지만, 인덱스를 적용하면 해당 고객의 주문 정보를 빠르게 찾을 수 있다.
  2. SELECT * FROM orders WHERE customer_id = 'C12345';
  3. JOIN 조건으로 자주 사용되는 컬럼
    • customer_id 컬럼에 인덱스가 있으면 조인 성능이 향상된다.
  4. SELECT * FROM customers c JOIN orders o ON c.customer_id = o.customer_id WHERE c.name = 'John Doe';
  5. ORDER BY, GROUP BY 절에서 정렬/그룹화할 때
    • category 컬럼에 인덱스를 설정하면 그룹화 연산이 빨라진다.
  6. SELECT category, COUNT(*) FROM products GROUP BY category;
  7. 대량 데이터에서 특정 범위 검색을 수행할 때
    • sale_date 컬럼에 인덱스가 없으면 전체 테이블을 스캔해야 하지만, 인덱스를 설정하면 원하는 범위 내의 데이터만 빠르게 찾을 수 있다.
  8. SELECT * FROM sales WHERE sale_date BETWEEN '2024-01-01' AND '2024-02-01';

2.2 JPA에서 자동으로 생성되는 인덱스

JPA에서는 특정 어노테이션을 사용하면 자동으로 인덱스가 생성된다.

  • 기본 키(@Id) 컬럼: 기본적으로 클러스터드 인덱스가 생성된다.
  • Unique 제약 조건이 있는 컬럼: @Column(unique = true) 설정 시 자동으로 인덱스가 추가된다.

예시:

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true)
    private String email;
}

위 코드에서 email 컬럼은 JPA가 자동으로 유니크 인덱스를 생성한다.

3. 인덱스를 많이 만들면 생기는 문제

인덱스가 많을수록 검색 속도가 향상될 것 같지만, 너무 많은 인덱스를 만들면 오히려 성능 저하를 유발할 수 있다.

그러므로 한 테이블당 3~5개 정도로 제한을 두고 생성하는 것을 권장한다.

3.1 데이터 삽입, 수정, 삭제 성능 저하

  • 데이터가 변경될 때마다 인덱스도 함께 갱신되어야 하므로, INSERT, UPDATE, DELETE 속도가 느려진다.

3.2 스토리지 공간 증가

  • 인덱스는 별도의 저장 공간을 차지하며, 너무 많으면 디스크 사용량이 증가한다.

3.3 불필요한 인덱스 탐색 비용 증가

  • 옵티마이저(Optimizer)는 실행 계획을 수립할 때 인덱스를 참고하는데, 인덱스가 너무 많으면 최적의 인덱스를 선택하는 데 오버헤드가 발생할 수 있다.
728x90
반응형
SMALL

'면접 준비' 카테고리의 다른 글

[면접 스터디용 질문 리스트] OS / DB / NETWORK/ MSA  (0) 2025.03.02
[면접 스터디용 질문 리스트] JAVA/SPRING/JPA/Redis/ 면접 질문 리스트 10개 씩  (0) 2025.03.02
[컴퓨터 구조 + 캐시 ] 우리가 Redis를 사용해서 캐시 메모리를 쓰는 이유  (1) 2024.12.05
면접 준비시 반드시 피해야 할 것들!  (2) 2024.11.12
백엔드 자바 CS 면접 빈출 질문 대비하기 - 데이터 베이스 개념 정리 1  (0) 2024.08.22
'면접 준비' 카테고리의 다른 글
  • [면접 스터디용 질문 리스트] OS / DB / NETWORK/ MSA
  • [면접 스터디용 질문 리스트] JAVA/SPRING/JPA/Redis/ 면접 질문 리스트 10개 씩
  • [컴퓨터 구조 + 캐시 ] 우리가 Redis를 사용해서 캐시 메모리를 쓰는 이유
  • 면접 준비시 반드시 피해야 할 것들!
공부하고 기억하는 공간
공부하고 기억하는 공간
IT 비전공자로 시작하여 훌륭한 개발자가 되기 위해 공부하고 있는 공간입니다. 틀린 내용이나 부족한 부분이 있으면 댓글로 알려주세요 바로 수정하겠습니다.
  • 공부하고 기억하는 공간
    IT - railroad
    공부하고 기억하는 공간
  • 전체
    오늘
    어제
    • 분류 전체보기 (329)
      • 면접 준비 (45)
        • OS (6)
        • Spring Security (0)
        • Java (3)
        • DB (11)
        • Network (3)
      • ElasticSearch (5)
      • Kafka (5)
      • Spring (60)
        • Spring Cloud (7)
        • Security6 (5)
        • JPA (12)
        • 프로젝트 리팩토링 회고록 (4)
        • Logging (8)
        • Batch (2)
      • Redis (17)
        • Redis 개념 (8)
        • Redis 채팅 (5)
        • Redis 읽기쓰기 전략 (1)
      • AWS (11)
      • 리눅스 (29)
        • 리눅스 마스터 2급 (5)
        • 네트워크(기초) (7)
        • 리눅스의 이해 (6)
        • 리눅스의 설치 (2)
        • 리눅스 운영 및 관리 (6)
      • JAVA-기초 (16)
        • JAVA기본 (11)
        • Design Pattern (5)
      • JSP (27)
        • JSP 기본 개념 (10)
        • JSP (1)
      • SQL (1)
      • TIL (36)
      • 문제 풀이 (39)
        • Programmers (9)
        • 백준 문제풀이 (28)
      • JavaScript (10)
      • HTML (17)
      • Ngrinder (1)
        • Ngrinder 문서 정리 (1)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      Springframework
      java
      자바 반복문
      JSP
      자바 면접
      CSS
      Til
      레디스
      프로그래머스
      자바
      jsp기초
      HTML
      자바 알고리즘
      spring redis
      Spring
      springsecurity
      JS
      redis 채팅
      redis
      자바 면접질문
      jsp request
      JavaScript
      자바기초
      Spring Data Redis
      리눅스
      백준
      자바스크립트
      스프링프레임워크
      리눅스마스터2급정리
      리눅스마스터2급
    • 최근 댓글

    • 최근 글

    • 250x250
    • hELLO· Designed By정상우.v4.10.3
    공부하고 기억하는 공간
    [CS -DB] Index 상식, JPA에서 자동생성하는 Index, Index가 많아지면 생기는 문제
    상단으로

    티스토리툴바