인덱스란?
인덱스는 데이터베이스에서 특정 컬럼이나 컬럼 조합의 값을 빠르게 찾기 위해 사용되는 자료구조이다. 쉽게 말해, 인덱스는 데이터를 정렬한 뒤 별도의 공간에 저장된다고 생각할 수 있다.
이를 통해 데이터베이스에서 데이터를 검색할 때 전체 테이블을 스캔하지 않고도 원하는 데이터를 신속하게 찾을 수 있다. 이는 책의 목차나 색인을 활용하여 필요한 정보를 빠르게 찾는 것과 유사하다.
예를 들어, 데이터가 9, 10, 5, 8, 7로 구성된 테이블이 있다고 가정해 본다면, 이 경우 인덱스는 5, 7, 8, 9, 10 순으로 정렬되어 저장된다.
원본 데이터 9 10 5 8 7
인덱스 정렬 | 5 | 7 | 8 | 9 | 10 |
7 이하 쿼리 결과 | 5 | 7 |
만약 쿼리를 통해 7 이하의 숫자를 추출하고자 할 때, 인덱스가 정렬되어 있기 때문에 5와 7만 스캔하면 된다. 그 이후에는 7보다 높은 숫자가 저장되어 있다는 것을 알 수 있으므로 추가적인 검색이 필요하지 않다.
인덱스의 구조
인덱스는 일반적으로 두 가지 주요 요소로 구성된다.
- 인덱스 컬럼: 인덱스가 생성된 테이블의 특정 컬럼
- ROWID: 인덱스가 가리키는 테이블의 레코드 위치를 나타내는 논리적인 주소
인덱스는 생성된 컬럼들과 ROWID가 서로 정렬되어 있는 자료구조를 가지고 있다. 이를 통해 특정 조건에 맞는 데이터를 빠르게 찾을 수 있다.
(ROWID는 데이터베이스 시스템에서 자동으로 생성되는 고유 식별자이며, 사용자가 직접 생성하는 것이 아니라 데이터베이스 관리 시스템(DBMS)이 각 행을 식별하기 위해 자동으로 할당한다.)
위의 그림에서 보는 바와 같이 인덱스는 인텍스를 생성시킨 컬럼인 EMPNO와 ROWID로 구성되어 있으며 각각 그 값들로 정렬되어 있다.
인덱스와 쿼리 처리
- 조건에 맞는 로우 스캔
- 인덱스를 통해 조건에 맞는 로우를 찾은 후, 해당 로우부터 차례대로 스캔한다. 예를 들어, EMPNO가 7800보다 큰 데이터가 필요하다면, 인덱스를 사용하여 7800보다 큰 첫 번째 값을 찾고, 그 이후 값을 순차적으로 접근한다.
- ROWID를 통한 테이블 접근
- 인덱스에서 찾은 ROWID를 사용하여 실제 테이블의 로우를 랜덤하게 액세스한다.
- 인덱스 로우의 순서와 테이블 로우의 순서가 일치하므로, 데이터 검색과 정렬이 효율적으로 이루어진다.
인덱스 장점
- 조건 검색 Where절의 효율성: 보통 Where절을 사용할 때 특정 조건에 맞는 데이터를 찾기 위해 데이터를 처음부터 끝까지 다 비교해야 하는데, 인덱스를 통해 데이터가 정렬되어 있으면 빠르게 찾아낼 수 있다.
- 정렬 Order by 정의 효율성: 인덱스를 사용하면 Order by에 의한 Sort과정을 피할 수 있다. 본래 Order by는 굉장히 부하가 많이 걸리는 작업이기 때문에 인덱스를 통해 이미 정렬되어 있으면 부하가 걸리지 않을 수 있다.
- MIN, MAX의 효율적인 처리가 가능: 이것또한 인덱스를 통해 데이터가 정렬되어 있기 때문에 처음부터 끝까지 뒤져서 찾는 것이 아닌 인덱스로 정렬된 데이터에서 MIN, MAX를 효율적으로 추출할 수 있다.
또한 인덱스는 데이터를 조회하는 SELECT 외에도 UPDATE나 DELETE의 성능이 함께 향상된다. 그러한 이유는 해당 연산을 수행하려면 해당 대상을 조회해야만 작업을 할 수 있기 때문이다.
- 성능 부하: INSERT, UPDATE, DELETE 명령어가 수행될 때 인덱스의 정렬을 유지해야 하므로 성능 부하가 발생할 수 있다.
- 비효율성: 데이터 양에 따라 인덱스 스캔이 풀 스캔보다 비효율적일 수 있다. 예를 들어, 데이터가 1개인 테이블은 인덱스 스캔보다 풀 스캔이 더 빠를것이다.
- 저장공간: 데이터베이스의 약 10%에 해당하는 추가 저장공간이 필요하다. 너무 많은 인덱스를 생성하면 전체 데이터베이스의 성능에 부하를 줄 수 있다. 때문에 SQL 문을 효율적으로 작성하고 인덱스는 신중하게 사용해야 한다.
'Databases' 카테고리의 다른 글
수직적 탐색 수평적 탐색 (0) | 2025.02.21 |
---|---|
NL 조인 (0) | 2025.02.07 |
DELETE vs TRUNCATE (0) | 2025.02.03 |
바인드 변수를 사용하는 이유 (0) | 2025.01.12 |
뷰(View)의 개념과 뷰(View)를 사용해야 하는 이유 (2) | 2024.12.06 |