Index
인덱스는 데이터베이스 테이블에 대한 검색 성능의 속도를 높여주는 자료 구조입니다. 특정 컬럼에 인덱스를 생성하면, 해당 컬럼의 데이터들을 정렬하여 별도의 메모리 공간에 데이터의 물리적 주소와 함께 저장됩니다. 이렇게 인덱스가 생성하였다면 앞으로 쿼리문에 "인덱스 생성 컬럼을 Where 조건으로 거는 등"의 작업을 하면 옵티마이저에서 판단하여 생성된 인덱스를 탈 수가 있습니다.
즉 인덱스는 책에 있는 목차라고 생각하시면 편합니다. 우리가 책에서 정보를 찾을때도 먼저 원하는 카테고리를 목차에서 찾고 목차에 있는 페이지 번호를 보고 찾아가듯 인덱스도 인덱스에서 내가 원하는 데이터를 먼저 찾고 저장되어 있는 물리적 주소로 찾아갑니다.
🏷️ Index의 장점
테이블에 데이터들이 인덱스의 가장 큰 특징은 데이터들이 정렬이 되어있다는 점입니다. 이 특징으로 인해 조건 검색이라는 영역에서 굉장한 장점이 됩니다.
✅ 조건 검색 Where 절의 효율성
테이블을 만들고 안에 데이터가 쌓이게 되면 테이블의 레코드는 내부적으로 순서가 없이 뒤죽박죽으로 저장됩니다. 이렇게 되면 Where절에 특정 조건에 맞는 데이터들을 찾아낼 때도 레코드의 처음부터 끝까지 다 읽어서 검색 조건과 맞는지 비교해야 하는데 이것을 풀 테이블 스캔 (Full Table Scan)이라고 합니다. 하지만 인덱스 테이블은 데이터들이 정렬되어 저장되어 있기 때문에 해당 조건 (Where)에 맞는 데이터들을 빠르게 찾기 을수 있습니다. 인덱스(Index)를 사용하는 가장 큰 이유입니다.
✅ 정렬 Order by 절의 효율성
인덱스(Index)를 사용하면 Order by에 의한 Sort과정을 피할 수가 있습니다. Order by는 굉장히 부하가 많이 걸리는 작업이기 때문에 메모리보다 큰 작업이 필요하다면 디스크 I/O도 추가적으로 발생됩니다. 하지만 인덱스를 사용하면 이미 정렬이 되어 있기 때문에 이러한 전반적인 자원의 소모를 하지 않아도 됩니다.
✅ MIN, MAX의 효율적인 처리
이것 또한 데이터가 정렬되어 있기 때문에 테이블을 다 뒤져서 작업하는 것이 아니라 MIN값과 MAX값을 레코드의 시작값과 끝 값 한건씩만 가져오면 돼서 훨씬 효율적으로 찾을 수 있습니다.
🏷️ Index의 단점
✅ 인덱스의 가장 큰 문제점은 정렬된 상태를 계속 유지 시켜줘야 합니다.
레코드 내에 데이터값이 바뀌는 부분이라면 악영향을 미칩니다. INSERT, UPDATE, DELETE를 통해 데이터가 추가되거나 값이 바뀐다면 INDEX 테이블 내에 있는 값들을 다시 정렬해야 합니. 그리고 Index 테이블, 원본 테이블 이렇게 두 군데에 데이터 수정 작업해줘야 한다는 단점도 있습니다.
✅ 검색시에도 인덱스가 무조건 좋은 것이 아닐 수도 있습니다.
인덱스는 테이블의 전체 데이터 중에서 10~15% 이하의 데이터를 처리하는 경우에만 효율적이고 그 이상의 데이터를 처리할 땐 인덱스를 사용하지 않는 것이 더 낫습니다. 그리고 인덱스를 관리하기 위해서는 데이터베이스의 약 10%에 해당하는 저장공간이 추가로 필요합니다. 그래서 무조건 Index를 만들어서는 결코 안 됩니다.
🏷️ Index의 구조
인덱스는 여러 자료구조를 이용해서 구현하 수 있는데, 대표적인 자료구조로 해시 테이블과 B+Tree가 있다.
✅ 해시 테이블(Hash Table)
해시 테이블은 컬럼의 값과 물리적 주소를 (key, value)의 한 쌍으로 저장하는 자료구조이지만 실제로 인덱스에서 잘 사용하지 않습니다.
그 이유는, 해시 테이블은 등호(=) 연산에 최적화되어있기 때문이다. 데이터베이스에선 부등호(<,>) 연산이 자주 사용되는데, 해시 테이블 내의 데이터들은 정렬되어 있지 않으므로 특정 기준보다 크거나 작은 값을 빠른 시간 내에 찾을 수가 없습니다.
✅ B+Tree
B+Tree는 대부분의 DBMS 그리고 오라클에서 특히 중점적으로 사용하고 있는 가장 보편적인 인덱스입니다. 구조는 Root Node(기준) / Branch Node(중간) / Leaf Node(말단)으로 구성되며 계층적 구조를 가지고 있습니다.
특정 컬럼에 인덱스를 생성하는 순간 컬럼의 값들을 정렬하는데, 정렬한 순서가 중간 쯤 되는 데이터를 뿌리에 해당하는 Root블록으로 지정하고 Root 블록을 기준으로 가지가 되는 Branch 블록을 정의하며 마지막으로 잎에 해당하는 Leaf 블록에 인덱스의 키가 되는 데이터와 데이터의 물리적 주소 정보인 ROWID를 저장합니다.
📖 Reference
'코딩 공부 > DB' 카테고리의 다른 글
[DB] NoSQL (3) | 2024.10.16 |
---|---|
[DB] Redis (0) | 2024.10.09 |