Database의 성능을 높이기 위한 여러 가지 방법들이 있습니다.(Index, 반정 규화, 클러스터링 등등) 이번에는 Index에 대해서 알아보겠습니다.

 

1. Index란?


Index란 추가적인 작업들을 통해서 테이블에서 데이터의 조회 속도를 향상시켜줄 수 있는 자료구조입니다. (시켜줄 수도 있다는 것은 Index를 잘못 사용했을 때 생기는 문제점입니다.)
말 그대로 Index는 색인입니다. 책이나 잡지를 볼 때 원하는 내용을 찾을 때 모든 페이지를 살펴본다면 오랜 시간이 소요됩니다. 하지만 책이나 잡지에는 색인을 추가해서 내용을 찾을 수 있도록 도움을 줍니다. 데이터베이스에 Index 또한 같은 역할을 합니다.

예시 사진을 보겠습니다.
Member_Id는 정렬돼 있고, 자신만의 포인트를 가지고있습니다. 따라서 테이블 전체를 살펴보는 것이 아닌 Member_Id의 Pointer만 살펴봐 성능을 향상할 수 있습니다.

2. Index 사용 주의점


조회 성능이 향상을 생각하고, 무조건 Index를 사용하는 것은 옳지 못한 생각입니다. Index 사용 주의점이 있습니다.

2-1. 조회 과정을 수행하지 않는 : Insert


조회 과정을 수행하지 않는 Insert의 경우 새로운 데이터가 삽입될때마다 Index를 최신화하도록 추가를 해줘야 합니다. 추가적인 연산이 필요하므로 성능 저하를 일으킬 수 있습니다.

 

2-2. 조회 과정 수행하는 : Select, Delete, Update

Select, Delete, Update는 조회를 시작으로 합니다. 조회에 대한 성능은 향상됩니다.

Select: 조회만함으로써 추가 연산이 없습니다.
Delete: 삭제하는 데이터의 Index를 사용하지 않도록 하는 작업(삭제는 아니다.) 후 추가적으로 진행합니다.
Update: 기존의 Index를 사용하지 않도록 하는 작업(삭제는 아니다.) 후 갱신된 Index를 추가합니다.

Select의 경우 추가 연산이 없으므로 성능 향상을 도모할 수 있지만, Delete와 Update의 경우 추가 연산으로 인해서 성능이 저하될 수 있습니다.

따라서 Delete, insert, Update가 많이 수행된다면, Index가 오히려 데이터보다 크기가 커져 성능이 떨어지는 것을 초래할 수 있습니다.

3. Index 사용하면 좋은 경우


3-1. 크기가 충분히 큰 테이블
3-2. Insert, Delete, Update가 자주 발생하지 않는 칼럼
3-3. Join, where Order by(Index가 정렬되어 있기 때문에 성능이 향상될 수 있습니다.)를 자주 사용하는 칼럼
3-4. 한 칼럼이 가지고 있는 데이터의 중복성이 낮은 칼럼(PK는 고윳값이므로 사용해도 무방)

 

4. Index 자료구조

 

4-1. Hash Table

Hash Table은 (Key, Value)로 데이터를 저장하고, Key값으로 고유한 Index를 생성하여 값을 O(1) 속도로 가져오는 자료구조입니다.
Hash Table의 경우 = 연산에만 특화돼 있습니다. 하지만 데이터베이스에서는 Like와 같은 부등호 연산을 수행하는 경우가 많습니다. 따라서 Hash Table의 경우 적합하지 않은 자료구조라고 생가합니다.

 

4-2. B-Tree, B+Tree

B-Tree: 균형 트리 형태로 존재하며 데이터가 정렬된 상태입니다. Key와 data를 가지고 있습니다. 이진트리와 유사하지만 자식 노드가 2개 이상 가능합니다. 하지만 Insert, Delete, Update의 연산을 통해서 점차 균형이 깨지고, 성능이 악화됩니다. 따라서 재구성을 해주는 작업이 필요할 수 있습니다.


B+Tree: B-Tree와는 다르게 브랜치 노드에 Key만 두고, data는 담아두지 않는다. 오직 리프 노드에만 Key와 data를 저장합니다. 리프 노드들은 Linked List로 연결돼 있습니다.
장점은 하나의 노드에 더 많은 Key값을 담을 수 있기 때문에 트리의 높이가 낮아집니다.(더 빠르게 탐색 가능)

출처: https://blog.jcole.us/2013/01/10/btree-index-structures-in-innodb/

5. Database에 Index 적용

Mysql로 진행했습니다. Member Table을 만든 후 member_id를 Index로 사용해보겠습니다.

Member Table 생성


member_id를 활용한 Index 생성


Index가 생성됐는지 확인하시려면 show index from (table이름); 해주시면 확인 가능합니다.

 

6. Spring Entity Index 설정하기

6-1. Table에 Index 설정하기

@Table(indexes = {@Index(name="index 이름", columnList = "데이터베이스에 삽입될 칼럼 이름 여기서는 name을 컬럼 이름이므로 name이다.")} Index는 여러 개 생성 가능하며, 여러 개의 칼럼을 사용해서 한 개의 Index를 만들 수 있습니다. 여기서는 name 한 개만을 이용해서 만들었습니다.

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@ToString(exclude = {"team"})
@Table(indexes = {@Index(name = "member_index",columnList = "member_id")})
public class Member{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "member_id")
    private Long id;

    @Column(name = "name",unique = true)
    private String name;

    @Column(name = "age")
    private int age;

    @Builder
    public Member(String name, int age){
        this.name=name;
        this.age=age;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "team_id")
    private Team team;

    public void changeAge(int age){
        this.age=age;
    }

    public void addTeam(Team team){
        team.getMembers().add(this);
        this.team=team;
    }
}

 

지금까지 Index란 무엇인지 알아보고, 설정을 해봤습니다. 읽어주셔서 감사합니다.

'SpringBoot > JPA' 카테고리의 다른 글

Spring-Data-JPA [8] Querydsl 사용  (0) 2022.06.09
Spring-Data-JPA [7] Querydsl 설정 (gradle 7.x)  (0) 2022.06.02
Spring-Data-JPA [5] Fetch Join  (0) 2022.03.24
Spring-data-JPA [4] Update와 @Query  (0) 2022.03.23
Spring-data-JPA [3] 명명법  (0) 2022.03.22