특정 DBMS에 대한 인덱스 구조가 아닌 데이터베이스 시스템 자체에 대한 인덱스에 대해 정리한다. 기본 개념, 종류와 메커니즘에 대해 말하겠다. 전체적인 흐름은 데이터베이스 시스템 (Abraham Silberschatz , Henry F. Korth , S. Sudarshan 저)의 14장 Indexing을 따른다. 1개 이상의 DBMS에서 인덱스를 생성해봤고, 인덱스에 대한 이해가 어느 정도 있다면 더 수월하게 포스팅을 읽어나갈 수 있을 것이다.
첫 번째 포스팅으로 데이터베이스에서 인덱스의 필요성과 기본 콘셉트를 정리한다.
목차
- 인덱스의 필요성
- 좋은 인덱스를 판별하는 기준
- search key
- 인덱스 생성하기
인덱스의 필요성
데이터베이스의 인덱스를 책의 색인에 비유하곤 한다.
책의 색인 | 데이터베이스 인덱스 | |
용도 | 특정 topic을 빨리 찾을 때 | 특정 record를 빨리 탐색 |
정렬 | 알파벳 순서로 정렬 | 특정 순서로 정렬 |
크기 | 전체 책의 일부 | 전체 record의 일부 |
Student라는 테이블이 있을때 만약 id 속성에 인덱스가 있다면 id 속성의 인덱스를 사용해 찾고자 하는 record를 빠르게 찾아들어갈 수 있다. (책의 색인처럼)
- 인덱스에 검색 조건 조회
- 인덱스를 통해 실제 record가 저장된 disk block 찾음
- 해당 disk block을 fetch
즉 인덱스는 질의 대상 record를 빠르게 특정할 수 있게 만드는 자료구조로서 실제 공간을 차지하는 데이터이다.
인덱스는 select 조건, join 조건에 자주 사용되는 속성이라면 query 시간을 단축시키기 때문에 고려해 볼 수 있다. 만약 Idol 테이블에 group_name = 'AESPA' 조건으로 조회시 group_name에 인덱스가 없다면, Idol 테이블의 모든 record를 실제로 읽어서 group_name이 'AESPA'인지 검사해야 한다. 그러나 인덱스를 통해 조회하면 인덱스에서 group_name이 'AESPA'인 record의 포인터를 가지고 있으므로 빠르게 record를 특정할 수 있다. (상대적으로 적은 I/O)
일단 1장이므로 빠른 이해를 도울 정도로 이 정도만 설명하고 넘어간다.
주의점
인덱스를 통해 record를 빠르게 특정할 수 있으니까 모든 컬럼에 대해 인덱스를 생성하면 될까? 그렇지 않다. 인덱스도 공간을 차지하는 데이터이기 때문에, 인덱스를 많이 생성할수록 배보다 배꼽이 커지게 된다. 리소스를 잡아먹기 때문이다.
또한 인덱스는 정렬되어있는 특성을 유지해야 하므로 테이블에 변경 (Insert, Update, Delete)가 발생하면 인덱스에도 수정이 필요하다. 이러한 추가작업은 overhead로 간주하며, 테이블에 무분별하게 생성된 인덱스로 인해 DML 성능이 떨어질 수 있다.
- 인덱스는 공간을 차지한다. 인덱스도 데이터다
- 인덱스가 있는 테이블에 수정이 발생하면 인덱스도 수정해주어야 한다
인덱스의 종류
- ordered index : 정렬되어 있는 인덱스
- hash index : hash 함수를 기반으로 record를 찾음. index 데이터를 bucket 단위로 균등하게 분포시켜 둠
인덱스는 크게 위와 같이 나뉜다. 어떤 형태로든 정렬이 되어있거나, 정렬되어있지 않으면 hash 함수를 통해 record를 특정해 찾아간다. DBMS 마다 적합한 인덱스와 세부구현은 조금씩 다르다.
좋은 인덱스를 판별하는 기준
무턱대고 인덱스를 생성하는 것이 좋지 않으니, 인덱스의 좋고 나쁨을 판단하는 기준이 필요하다. 크게 5가지가 있다.
- Access type : index를 통해 어떤 식으로 접근하는가 (범위 연산, = 연산)
- Access time : access 소요시간
- Insertion time : Insert 소요 시간 (인덱스에 추가할 공간을 찾는 시간 + 추가 후 재정렬 시간)
- Deletion time : Delete 소요 시간 (인덱스에 삭제 대상을 찾는 시간 + 삭제 후 재정렬 시간
- Space overhead : 인덱스가 차지하는 공간
위 다섯 가지를 통해 인덱스를 평가할 수 있다. 그 오에도 상황에 따라 추가 요소들이 있을 수 있으며 위 5가지도 목적에 따라 그 중요성의 우선순위가 다를 수 있다.
search key
한국말로 탐색키 정도로 번역해 볼 수 있을 것 같다. 디스크에 저장된 실제 record를 찾는 데 사용되는 속성 (attribute)를 의미한다. 만약 Student 테이블에 id, name, age 속성이 있다면, search key는 id, name, age, (name, age) 등이 모두 가능하다. key가 붙었다고 해서 Primary key, Super key 등과 혼동하지 않기 바란다. search key는 말 그대로 search 하는 데 사용되는 key에 불과하다.
따라서 search key의 record가 1개 이상일 수 있다. Student 테이블에 name 속성이 "카리나"인 record를 질의하면 당연히 동명이인으로 1개 이상의 record가 있을 수 있다. 이를 nonunique search key라고 한다. Student 테이블의 name 속성은 nonunique search key이다. (name 속성에 unqiue 제약조건이 없으므로)
인덱스 생성하기
sql 표준은 인덱스 생성 구문을 정의하지 않았지만, 대부분의 DBMS들은 인덱스 생성 DDL을 지원, 비슷하다.
-- create
create index <index-name > on <relation-name> (<attribute-list>);
-- drop
drop index <index-name>;
-- e.g. idol 테이블에 group_name 속성에 group_idx 이름으로 인덱스 생성
create index group_idx on idol (group_name);
위처럼 인덱스를 생성할 수 있고, 세션에서 SQL query를 실행하면, 인덱스를 사용 가능한 query인지 DB가 판단해서 자동으로 인덱스를 통해 query를 실행한다. (인덱스 사용 가능 query인지 판별하는 것은 포스팅 범위를 넘어가므로 생략)
실제 DBMS에서의 인덱스 생성
대부분의 DBMS들은 Primary key를 생성하면 해당 속성에 대한 인덱스를 자동으로 생성해 준다. 만일 PK 속성에 인덱스가 없다면, INSERT 작업 시 PK 정합성 검사를 모든 record를 직접 탐색해 가며 진행해야 한다. 주의할 점은 FK 속성에 대해서는 대부분의 DBMS가 인덱스를 생성하지 않는다는 것이다. 이 때는 수동으로 인덱스를 추가해 주는 것이 좋다. 보통 FK는 그 속성을 join이나 select 조건에 자주 사용하게 될 것이기 때문이다.
일부 DBMS의 경우 DBA의 개입 없이 DB가 자체적으로 인덱스를 생성해 주는 것을 지원해준다고 한다.
인덱스 이야기는 아래 포스팅으로 이어진다.
https://kghworks.tistory.com/150
참고
https://product.kyobobook.co.kr/detail/S000001693775
'Programming > Database System' 카테고리의 다른 글
[Database] 인덱스 (Index) 3장 : B+-Tree Index 기본 (0) | 2023.10.19 |
---|---|
[Database] 인덱스 (Index) 2장 : Ordered Index (순서 인덱스) (0) | 2023.10.12 |
[개발일지] 채번(採番) 개발하기 (0) | 2023.10.05 |
[DBMS] PK 선정 전략 - surrogate key와 natural key (0) | 2023.01.15 |
[ORACLE] Lock 1편 - Lock의 개념과 매커니즘 (0) | 2022.10.12 |
댓글