Index 란
업데이트:
Index
데이터베이스에서 인덱스란 데이터베이스의 데이터 검색 동작 속도를 높여주는 자료구조로, 탐색 키와 실제 레코드를 가리키는 포인터로 구성되어 있다. 아래 이미지와 같이 별도의 공간에 데이터의 주소와 함께 정렬된 형태로 저장된다. 이미지에 언급된 링크에서 데이터를 찾는 애니메이션도 볼 수 있어 이해하기 쉬울 것 같다.
인덱스는 보통 책의 목차에 비유된다. 책을 읽을 때 목차가 없다면 페이지 수가 많을수록, 찾는 내용이 후반부에 있을수록 원하는 내용을 찾을 때 소요되는 시간이 늘어날 것이다. 이 때 목차가 있다면 찾고자 하는 내용이 어디 있는지 알게 되고, 빠르게 찾을 수 있을 것이다.
책을 데이터베이스, 찾고자 하는 내용을 데이터로 생각한다면 인덱스는 데이터 검색에 소요되는 시간을 줄여준다는 것을 알 수 있다.
장점
👍 효율적인 조건 검색
특정 조건에 맞는 데이터를 찾는 WHERE 를 사용할 때, 인덱스가 없다면 테이블 전체(Full Table Scan)를 탐색하게 되어 위에서 말했던 책과 같이 시간이 오래 걸리게 된다. 하지만 인덱스가 있다면 빠르게 찾을 수 있다.
👍 효율적인 정렬
데이터를 정렬할 때 ORDER BY 를 사용하는데, 인덱스를 사용한다면 이미 정렬이 되어있기에 정렬 과정을 생략할 수 있다.
👍 효율적인 최소, 최댓값
이미 정렬이 되어있기 때문에 첫번째 값과 마지막 값을 가져오면 최소, 최댓값을 바로 구할 수 있다.
👍 시스템의 전반적인 부하 감소
단점
👎 인덱스 관리
인덱스를 항상 정렬된 상태로 유지해야 하기에 데이터를 INSERT, DELETE, UPDATE 할 때 아래와 같은 추가 작업이 필요하다.
- INSERT: 새로운 데이터에 대한 인덱스 추가
- DELETE: 삭제하는 데이터의 인덱스를 사용하지 않는다 작업
- UPDATE: 기존의 인덱스를 사용하지 않는다 작업 후 갱신된 데이터에 대한 인덱스 추가
💡 인덱스를 사용하지 않는다: 데이터를 INSERT, DELETE, UPDATE가 수행될 때마다 정렬을 해주어야 하고 그에 따른 부하가 발생하는데, 이를 최소화하기 위해 삭제라는 개념 대신 ‘인덱스를 사용하지 않는다’ 라는 작업을 한다.
👎 추가 저장 공간 필요
인덱스를 관리하기 위해서는 데이터베이스의 약 10%에 해당하는 저장 공간이 필요하다.
👎 성능 저하 가능성
데이터의 갱신이 잦은 속성에 인덱스를 건다면 자주 정렬을 해주어야 하고 인덱스 테이블과 원본 테이블 두 곳의 데이터 수정 작업을 해주어야 한다. 또한 인덱스 제거가 아닌 사용하지 않는다는 작업을 하기 때문에 인덱스 테이블의 크기가 비대해져 오히려 성능이 저하될 수 있다.
효율적인 인덱스 사용
- 중복도가 낮은 컬럼 → Cardinality가 높은 컬럼
- 조건절에 자주 등장하는 컬럼
- JOIN, WHERE, ORDER BY 절에서 자주 사용되는 컬럼
- 규모가 큰 테이블
- INSERT, DELETE, UPDATE 작업이 자주 발생하지 않는 컬럼
Index 종류
Index의 종류로는 아래와 같은데, 이 중 Primary와 Secondary에 대해 알아보자.
Primary Index
일반적으로 Primary key에 기반하여 생성된 인덱스를 Primary Index 라 한다. (Primary key만 사용 가능한 것은 아니다.) Primary Index는 레코드와 1:1 관계를 갖는다. 즉, 각 레코드에 고유하다. 주로 dense index와 sparse index 로 나뉜다.
dense index
- 데이터베이스의 모든 키가 인덱스에서 표현 됨
- 인덱스들이 데이터 자체 순서와 동일하게 유지
- 데이터 탐색을 빠르게 하지만 인덱스 저장을 위한 공간이 필요
- 탐색 키와 실제 레코드의 주소로 구성
sparse index
- dense index의 단점 보완
- dense index는 모든 탐색 키를 갖고 있기에 비교적 큼
- 데이터 블록마다 한 개의 인덱스
- 블록은 각 레코드를 식별할 수 있을 만큼의 정보를 갖고 있어야 함
- 데이터 탐색을 하는데 더 많은 시간 소요
Secondary Index
Secondary Index는 말 그대로 다른 인덱스를 돕는 보조 인덱스로 레코드의 위치가 어디인지 알려주는 역할을 한다.
- 데이터가 정렬되어 있지 않음
- 데이터 블록이 아닌 각 레코드마다 한 개의 인덱스 (dense index)
- 인덱스 하나에 대해 여러 레코드 발생
Primary vs. Secondary
- | Primary Index | Secondary Index |
---|---|---|
정의 | 고유한 키 값을 갖는 인덱스 | Primary 인덱스 이외에 중복이 가능한 인덱스 |
정렬 | 데이터가 정렬되어 있어야 함 | 데이터가 정렬되어 있지 않음 |
개수 | 하나만 가능 | 여러 개 가능 |
중복 가능 여부 | 불가능 | 가능 |
Composite Index
Composite Index도 역시 말 그대로 여러 컬럼을 결합하여 인덱스를 생성하는 것을 말한다. 예를 들어 아래와 같은 테이블이 있다고 하자.
id | name | gender | class |
---|---|---|---|
1 | 철수 | 남 | 수학 |
2 | 영희 | 여 | 수학 |
3 | 민지 | 여 | 과학 |
4 | 민수 | 남 | 수학 |
5 | 영택 | 남 | 과학 |
6 | 소희 | 여 | 수학 |
이 테이블에서 수학을 듣는 여자와 과학을 듣는 남자를 찾는 질의가 잦아 인덱스 테이블을 만든다면, 아래와 같을 것이다.
과학_남자 | 5 |
과학_여자 | 3 |
수학_남자 | 1 |
수학_남자 | 4 |
수학_여자 | 2 |
수학_여자 | 6 |
Composite Index는 빈도수가 적은 인덱스를 먼저 거는 게 좋은데, 위에서 남자_과학이 아닌 과학_남자로 한 것이 그 이유이다. 남자 중에서 과학을 듣는 사람을 찾는 것 보다 과학을 듣는 사람 중에서 남자인 사람을 찾는 것이 더 효율적이기 때문이다. 이에 주의하여 인덱스를 생성해야 한다. 사실 데이터의 양이 적어 비슷하긴 하지만 사람이 더 많다고 가정을 해보자..
이를 활용하면 ~이면서 ~인 조건(WHERE … AND …)일 때의 데이터 탐색에 더 적은 시간이 소요될 것이다.
댓글남기기