데이터베이스에서의 인덱스(Index)는 데이터베이스 테이블 내의 특정 열(Column)에 대한 검색 속도를 향상시키기 위해 사용되는 데이터 구조입니다. 인덱스는 데이터의 빠른 검색과 정렬을 가능하게 하며, 데이터베이스 성능을 향상시키는데 중요한 역할을 합니다.
인덱스의 작동 원리는 데이터베이스 테이블의 열에 대한 특정 값을 키로 사용하여 이 값과 해당 행의 위치를 매핑하는 것입니다. 이를 통해 검색 연산 시 전체 테이블을 순차적으로 탐색하는 것이 아니라 인덱스를 탐색하여 검색 대상을 빠르게 찾을 수 있습니다.
DBMS는 index를 항상 최신의 정렬된 상태로 유지해야 원하는 값을 빠르게 탐색할 수 있습니다. 그렇기 때문에 인덱스가 적용된 컬럼에 INSERT, UPDATE, DELETE가 수행된다면 각각 다음과 같은 연산을 추가적으로 해주어야 하며 그에 따른 오버헤드가 발생합니다.
해시 테이블은 컬럼의 값과 물리적 주소를 (key, value)의 한 쌍으로 저장하는 자료구조입니다. 하지만 해시 테이블은 실제로 인덱스에서 잘 사용하지 않습니다.
그 이유는, 해시 테이블은 등호(=) 연산에 최적화되어있기 때문입니다. 데이터베이스에선 부등호(<,>) 연산이 자주 사용되는데, 해시 테이블 내의 데이터들은 정렬되어 있지 않으므로 특정 기준보다 크거나 작은 값을 빠른 시간 내에 찾을 수가 없습니다.
B+Tree는 대부분의 DBMS 그리고 오라클에서 특히 중점적으로 사용하고 있는 가장 보편적인 인덱스입니다. 구조는 Root Node(기준)/Branch Node(중간)/Leaf Node(말단)으로 구성되며 계층적 구조를 가지고 있습니다.
검색 속도 향상: 인덱스를 통해 특정 열을 검색할 때 데이터베이스는 테이블 전체를 스캔하지 않고 인덱스를 사용하여 검색 속도를 대폭 향상시킬 수 있습니다.
정렬 및 그룹화: 인덱스를 사용하면 데이터를 정렬된 상태로 유지할 수 있어서 정렬된 결과를 빠르게 가져올 수 있으며, 그룹화된 결과도 더 효율적으로 처리할 수 있습니다.
고유성 보장: 고유성(unique) 인덱스를 생성하여 특정 열의 값이 중복되지 않도록 보장할 수 있습니다.
쿼리 최적화: 인덱스를 사용한 쿼리 실행 계획을 최적화하여 데이터베이스의 성능을 향상시킵니다.
공간 사용: 인덱스는 추가적인 저장 공간을 필요로 하며, 데이터베이스 크기를 증가시킬 수 있습니다.
갱신 오버헤드: 데이터의 삽입, 갱신, 삭제 연산 시 인덱스를 갱신하는 작업도 추가로 수행되기 때문에 갱신 작업이 느려질 수 있습니다.
갱신 이상: 인덱스를 많이 사용하면 데이터의 갱신 작업 시 데이터의 일관성을 유지하기 어려울 수 있습니다.
선택도 문제: 인덱스를 생성할 열을 신중하게 선택하지 않으면 불필요한 인덱스가 추가되어 쿼리의 성능이 저하될 수 있습니다.
큰 테이블에서의 성능 감소: 대량의 데이터가 있는 테이블에서는 인덱스를 사용하더라도 검색 성능이 급격하게 저하될 수 있습니다.
✏️ 인덱스를 사용하는 것 만큼이나 생성된 인덱스를 관리해주는 것도 중요합니다. 그러므로 사용되지 않는 인덱스는 바로 제거를 해주어야 합니다.
인덱스가 적용된 컬럼에 정렬을 변경시키는 INSERT, UPDATE, DELETE 명령어가 수행된다면 계속 정렬을 해주어해서 그에 따른 부하가 발생합니다. 이런 부하를 최소화하기 위해 인덱스는 데이터 삭제라는 개념에서 인덱스를 사용하지 않는다 라는 작업으로 이를 대신한다.
검색을 위주로 하는 테이블에 인덱스를 생성하는 것이 좋지만 무조건 인덱스가 검색에 좋은 것은 아닙니다. 예를 들어, 1개의 데이터가 있는 테이블과 100만개의 데이터가 들어 있는 테이블이 있다고 가정한다면, 100만 개의 데이터가 들어있는 테이블이라면 풀 스캔보다는 인덱스 스캔이 유리하겠지만, 1개의 데이터가 들어있는 테이블은 인덱스 스캔보다 풀 스캔이 더 빠릅니다.
3.속도 향상을 위해 인덱스를 많이 만드는 것이 좋지 않다.
인덱스를 관리하기 위해서는 데이터베이스의 약 10%에 해당하는 저장공간이 추가로 필요합니다. 때문에 너무 많이 인덱스를 생성하면 하나의 쿼리문을 빠르게 만들 수 있지만 대신에 전체적인 데이터베이스의 성능 부하를 초래합니다. 때문에 무조건적인 인덱스 생성보다 SQL문을 효율적으로 짜고, 인덱스 생성은 마지막 수단으로 사용해야합니다.
피드백 및 개선점은 댓글을 통해 알려주세요😊