본문 바로가기
DataBase

Index Scan과 Index Seek

by 대박플머 2024. 9. 17.

데이터베이스 성능 최적화에 있어서 인덱스는 매우 중요한 역할을 합니다. 하지만 인덱스를 사용해도 그 방식에 따라 성능에 큰 차이가 있을 수 있습니다. 여기서는 데이터베이스 쿼리에서 자주 나오는 두 가지 인덱스 접근 방식인 Index ScanIndex Seek의 차이를 설명하고, 각 방식이 언제 발생하는지, 그리고 어떤 상황에서 사용되는지에 대해 실제 테이블과 인덱스 예제를 통해 자세히 알아보겠습니다.

Index Scan vs Index Seek의 차이

Index ScanIndex Seek은 데이터베이스 인덱스를 활용하는 방식에서 큰 차이를 보입니다.

  • Index Scan: 인덱스를 처음부터 끝까지 순차적으로 읽습니다. 이는 일반적으로 쿼리의 조건에 해당하는 인덱스가 없거나, 조건이 너무 범위가 넓을 때 발생합니다. 예를 들어, 테이블의 모든 데이터를 탐색해야 하는 경우 Index Scan이 사용됩니다.
  • Index Seek: 인덱스를 사용해 필요한 데이터만 빠르게 찾아내는 방식입니다. 이는 주로 쿼리의 조건이 인덱스 컬럼과 일치하거나, 매우 적은 범위 내에서 일치하는 경우에 발생합니다. Index Seek는 성능 측면에서 훨씬 효율적이며, 테이블에서 특정한 레코드를 빠르게 찾아낼 수 있습니다.

Index Scan이 발생하는 상황

Index Scan은 다음과 같은 상황에서 발생할 수 있습니다:

  1. 인덱스가 없을 때: 테이블에 인덱스가 전혀 없거나, 인덱스가 설정된 컬럼이 쿼리 조건에 사용되지 않는다면, 데이터베이스는 테이블 전체를 탐색해야 하므로 Index Scan이 발생합니다.
  2. 널리 퍼진 범위 조건: LIKE, 범위 조건 (<, >, BETWEEN)을 사용할 때 검색하는 범위가 넓으면 인덱스를 사용할 수 없고, 전체 데이터를 탐색하는 Index Scan이 발생합니다.
  3. 조건이 인덱스에 맞지 않을 때: 쿼리에서 사용하는 조건이 특정 인덱스의 정렬 방식과 일치하지 않으면, Index Scan을 사용하여 데이터를 검색할 수 있습니다.

Index Seek이 발생하는 상황

Index Seek은 다음과 같은 경우에 발생합니다:

  1. 정확한 매칭 조건: = 연산자를 사용하여 특정 값을 찾을 때, 인덱스를 사용해 필요한 레코드를 빠르게 찾을 수 있습니다.
  2. 인덱스와 일치하는 조건: 쿼리의 조건이 인덱스 컬럼에 정확히 일치하거나, 제한된 범위 내에서 일치할 때 Index Seek이 발생합니다.
  3. 클러스터 인덱스 사용: 클러스터 인덱스는 기본적으로 테이블의 데이터가 인덱스에 정렬되어 있기 때문에, 특정 값을 빠르게 검색할 수 있습니다.

실무 예제: 실제 테이블에서의 Index Scan과 Index Seek

다음 예제는 MySQL에서 Index Scan과 Index Seek이 어떻게 발생하는지 설명합니다. 우리는 employees라는 테이블과 그에 대한 인덱스를 설정한 후, 각 상황에서 두 방식이 어떻게 다른지 살펴보겠습니다.

테이블 생성 및 데이터 삽입

CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    department_id INT,
    salary DECIMAL(10, 2)
);

-- 인덱스 추가
CREATE INDEX idx_department_id ON employees(department_id);

-- 예시 데이터 삽입
INSERT INTO employees (employee_id, first_name, last_name, department_id, salary)
VALUES
(1, 'John', 'Doe', 1, 50000),
(2, 'Jane', 'Smith', 2, 60000),
(3, 'Robert', 'Brown', 1, 45000),
(4, 'Lucy', 'Johnson', 3, 70000);

Index Scan 예시

아래 쿼리에서는 department_id에 인덱스가 존재하지만, 쿼리 조건이 모든 레코드를 검색해야 하기 때문에 Index Scan이 발생합니다.

EXPLAIN SELECT * FROM employees WHERE salary > 40000;

이 경우 salary 컬럼에는 인덱스가 없기 때문에 MySQL은 테이블의 모든 레코드를 확인해야 합니다. 이는 Index Scan이 발생하는 전형적인 예입니다.

Index Seek 예시

아래 쿼리는 department_id에 인덱스가 설정되어 있기 때문에, Index Seek을 통해 필요한 레코드만 빠르게 찾을 수 있습니다.

EXPLAIN SELECT * FROM employees WHERE department_id = 1;

이 쿼리는 department_id에 정확히 일치하는 레코드를 찾기 때문에, 인덱스를 사용해 빠르게 데이터를 가져옵니다. 이는 Index Seek이 발생하는 상황입니다.

Index Scan과 Index Seek의 성능 차이

두 방식의 가장 큰 차이는 성능입니다. Index Scan은 테이블의 모든 데이터를 읽기 때문에, 레코드가 많을수록 성능이 저하될 수 있습니다. 반면, Index Seek은 필요한 데이터만 선택적으로 읽기 때문에, 훨씬 빠르고 효율적입니다.

다음은 두 쿼리 방식의 성능을 비교하는 간단한 예시입니다:

-- Index Scan: 모든 데이터를 읽음
SELECT * FROM employees WHERE salary > 40000;

-- Index Seek: 인덱스를 사용해 특정 레코드만 읽음
SELECT * FROM employees WHERE department_id = 1;

만약 employees 테이블에 100만 개의 레코드가 있다고 가정한다면, 첫 번째 쿼리는 전체 레코드를 순차적으로 탐색해야 하므로 시간이 오래 걸릴 수 있지만, 두 번째 쿼리는 인덱스를 사용해 빠르게 데이터를 찾을 수 있습니다.

결론

Index ScanIndex Seek은 인덱스를 사용하는 방식에서 큰 차이가 있으며, 이로 인해 쿼리 성능에도 큰 영향을 미칩니다. Index Scan은 전체 데이터를 탐색할 때 발생하고, Index Seek은 특정 조건에 맞는 데이터를 빠르게 찾을 때 발생합니다. 따라서 인덱스를 적절히 설계하고, 쿼리 조건에 맞는 인덱스를 사용하는 것이 성능 최적화의 핵심입니다.

실무에서 데이터베이스 성능을 향상시키기 위해서는 인덱스의 설계와 쿼리 작성이 매우 중요합니다. 특히, 대량의 데이터를 처리할 때는 Index Seek을 최대한 활용할 수 있도록 쿼리와 인덱스를 조정하는 것이 좋습니다.