본문 바로가기
카테고리 없음

DB에서 index는 어떤 식으로 작동하는가?

2024. 7. 24.

데이터베이스에서 인덱스(index)는 검색 성능을 향상시키기 위해 사용되는 데이터 구조입니다. 인덱스는 데이터베이스 테이블의 하나 이상의 열에 대해 생성될 수 있으며, 인덱스를 사용하면 테이블의 특정 행을 빠르게 찾을 수 있습니다. 인덱스는 책의 색인과 유사한 역할을 하며, 책의 특정 페이지를 빠르게 찾을 수 있는 것처럼 데이터베이스에서도 원하는 데이터를 빠르게 찾을 수 있게 합니다.

인덱스의 작동 방식은 다음과 같습니다:

1. **인덱스 생성**:
    - 인덱스를 생성할 때, 데이터베이스는 선택된 열의 값을 기반으로 별도의 데이터 구조(예: B-트리, 해시)를 생성합니다.
    - 예를 들어, `CREATE INDEX index_name ON table_name(column_name);` 와 같이 SQL 명령어를 사용하여 인덱스를 생성할 수 있습니다.

2. **데이터 구조**:
    - **B-트리**: 대부분의 관계형 데이터베이스에서 사용하는 인덱스 구조입니다. B-트리는 균형 이진 트리의 일종으로, 노드가 자식 노드로의 포인터를 가지며 검색, 삽입, 삭제 작업에서 효율적입니다.
    - **해시**: 일부 데이터베이스에서는 해시 테이블을 사용하여 인덱스를 구현합니다. 해시는 정확한 매칭을 필요로 하는 검색에 유용합니다.

3. **검색 과정**:
    - 인덱스를 사용하여 데이터를 검색할 때, 데이터베이스는 먼저 인덱스에서 검색할 키 값을 찾습니다.
    - 인덱스에서 키 값을 찾은 후, 해당 키 값에 연결된 테이블의 실제 데이터 위치를 참조합니다.
    - 예를 들어, `SELECT * FROM table_name WHERE column_name = 'value';` 를 실행할 때, 데이터베이스는 `column_name`에 대해 생성된 인덱스를 사용하여 'value'에 해당하는 행을 빠르게 찾습니다.

4. **인덱스 유지보수**:
    - 테이블에 데이터를 삽입, 수정, 삭제할 때마다 인덱스도 업데이트되어야 합니다. 이는 인덱스 유지보수 비용을 증가시키며, 너무 많은 인덱스를 생성하면 오히려 성능이 저하될 수 있습니다.
    - 따라서, 인덱스는 자주 검색되는 열이나 조건에 대해 전략적으로 생성하는 것이 중요합니다.

5. **커버링 인덱스(Covering Index)**:
    - 인덱스가 검색 조건에 사용되는 열뿐만 아니라 선택되는 열도 포함하면, 데이터베이스는 인덱스만으로 쿼리를 처리할 수 있어 더욱 빠른 성능을 발휘할 수 있습니다.

### 예시

예를 들어, 다음과 같은 테이블이 있다고 가정합니다:

```sql
CREATE TABLE employees (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    department VARCHAR(100),
    salary INT
);
```

다음과 같은 쿼리를 자주 실행한다고 가정합니다:

```sql
SELECT * FROM employees WHERE department = 'Sales';
```

이 경우, `department` 열에 인덱스를 생성하면 검색 성능이 향상될 수 있습니다:

```sql
CREATE INDEX idx_department ON employees(department);
```

이렇게 인덱스를 생성하면, 데이터베이스는 `employees` 테이블의 `department` 열에 대해 인덱스를 사용하여 'Sales' 부서의 직원을 빠르게 찾을 수 있습니다. 

이와 같이 인덱스는 데이터베이스 성능 최적화의 중요한 도구이며, 적절히 사용하면 검색 성능을 크게 향상시킬 수 있습니다. 그러나 인덱스 생성과 유지보수에는 비용이 따르므로, 쿼리 패턴과 데이터 변경 빈도를 고려하여 신중하게 설계하는 것이 중요합니다.

 

 

다음은 `employees` 테이블과 `department` 열에 대한 인덱스를 생성한 후 쿼리를 실행하는 과정을 표로 정리한 것입니다.

### employees 테이블 구조

| id  | name    | department | salary |
|-----|---------|------------|--------|
| 1   | John    | Sales      | 50000  |
| 2   | Jane    | Engineering| 60000  |
| 3   | Alice   | Sales      | 55000  |
| 4   | Bob     | HR         | 45000  |
| 5   | Charlie | Sales      | 52000  |

### 인덱스 생성

```sql
CREATE INDEX idx_department ON employees(department);
```

### 인덱스 구조 (B-트리 예시)

| department | Row ID(s) |
|------------|-----------|
| Engineering| 2         |
| HR         | 4         |
| Sales      | 1, 3, 5   |

### 쿼리 실행

```sql
SELECT * FROM employees WHERE department = 'Sales';
```

### 인덱스 사용 과정

1. **인덱스 검색**:
   - `department = 'Sales'`를 가진 인덱스 항목을 찾음
   - 해당 항목의 Row ID(s)는 1, 3, 5

2. **실제 데이터 검색**:
   - Row ID 1, 3, 5에 해당하는 데이터를 `employees` 테이블에서 검색

### 검색 결과

| id  | name    | department | salary |
|-----|---------|------------|--------|
| 1   | John    | Sales      | 50000  |
| 3   | Alice   | Sales      | 55000  |
| 5   | Charlie | Sales      | 52000  |

### 전체 과정 요약 표

| 단계         | 설명                                                                                  |
|--------------|---------------------------------------------------------------------------------------|
| 인덱스 생성  | `CREATE INDEX idx_department ON employees(department);`                               |
| 인덱스 검색  | `department = 'Sales'` 항목을 인덱스에서 검색하여 Row ID(s) 1, 3, 5 획득               |
| 실제 데이터 검색 | Row ID 1, 3, 5에 해당하는 데이터를 `employees` 테이블에서 검색                        |
| 검색 결과    | | 1 | John    | Sales      | 50000 | 3 | Alice   | Sales      | 55000 | 5 | Charlie | Sales      | 52000 | |

이 표는 인덱스 생성부터 검색 결과 도출까지의 과정을 시각적으로 보여줍니다. 인덱스를 통해 `department`가 'Sales'인 데이터를 빠르게 찾을 수 있음을 알 수 있습니다.

댓글