콘텐츠로 이동

비트맵 인덱스 스캔 vs 인덱스 스캔 vs 테이블 스캔

데이터베이스 쿼리 실행 시 데이터를 검색하는 방법은 크게 세 가지로 나눌 수 있습니다: 비트맵 인덱스 스캔(Bitmap Index Scan), 인덱스 스캔(Index Scan), 그리고 테이블 스캔(Table Scan). 각 방식은 서로 다른 상황에서 최적의 성능을 제공합니다.

테이블 스캔 (Table Scan / Sequential Scan)

테이블 스캔은 가장 기본적인 데이터 접근 방식으로, 테이블의 모든 레코드를 처음부터 끝까지 순차적으로 읽는 방식입니다.

특징

  • 테이블의 모든 행을 읽음
  • 인덱스를 사용하지 않음
  • 디스크에서 모든 데이터 블록을 순차적으로 읽음

적합한 상황

  • 작은 테이블에서 데이터를 검색할 때
  • 테이블의 대부분의 행을 검색해야 할 때 (일반적으로 테이블의 10-15% 이상)
  • 적절한 인덱스가 없을 때

장점

  • 구현이 간단함
  • 작은 테이블에서는 효율적일 수 있음
  • 대량의 데이터를 검색할 때 인덱스 스캔보다 효율적일 수 있음

단점

  • 대용량 테이블에서는 매우 느림
  • 모든 데이터를 읽어야 하므로 I/O 비용이 높음

인덱스 스캔 (Index Scan)

인덱스 스캔은 테이블에 생성된 인덱스를 사용하여 데이터에 접근하는 방식입니다.

특징

  • B-Tree와 같은 인덱스 구조를 통해 데이터에 접근
  • 인덱스를 통해 필요한 레코드의 위치를 찾은 후 테이블에서 해당 레코드를 가져옴
  • 인덱스 순서대로 데이터를 읽음

적합한 상황

  • 소수의 행을 검색할 때 (일반적으로 테이블의 1-5%)
  • 검색 조건이 인덱스 컬럼에 적용될 때
  • 정렬된 결과가 필요할 때 (인덱스 컬럼 기준)

장점

  • 소량의 데이터를 검색할 때 매우 효율적
  • 정렬된 결과를 얻을 수 있음
  • 특정 범위의 데이터를 빠르게 검색 가능

단점

  • 인덱스 유지 관리에 추가 비용 발생
  • 많은 행을 검색할 때는 테이블 스캔보다 비효율적일 수 있음
  • 인덱스 검색 후 테이블 접근(Random I/O)이 많아지면 성능 저하

비트맵 인덱스 스캔 (Bitmap Index Scan)

비트맵 인덱스 스캔은 비트맵 인덱스를 사용하거나, 일반 인덱스를 비트맵으로 변환하여 여러 조건을 효율적으로 처리하는 방식입니다.

특징

  • 각 레코드의 존재 여부를 비트(0 또는 1)로 표현
  • 여러 조건의 비트맵을 AND, OR 연산으로 결합 가능
  • 결과 비트맵을 사용하여 테이블에서 필요한 레코드만 접근

적합한 상황

  • 여러 인덱스를 사용하는 복합 조건 검색
  • 중간 규모의 결과 집합(테이블의 약 5-10%)을 반환할 때
  • 낮은 카디널리티(중복이 많은) 컬럼에 대한 검색

장점

  • 여러 조건을 효율적으로 결합 가능
  • 중간 규모의 결과 집합에서 효율적
  • 테이블 접근을 최소화하고 순차적으로 처리

단점

  • 매우 적은 수의 행을 검색할 때는 일반 인덱스 스캔보다 오버헤드가 클 수 있음
  • 비트맵 생성 및 조작에 추가 메모리 필요
  • 동시성 제어에 제약이 있을 수 있음

성능 비교

스캔 유형 적은 데이터 검색 중간 규모 데이터 검색 대량 데이터 검색
테이블 스캔 비효율적 중간 효율적
인덱스 스캔 매우 효율적 중간 비효율적
비트맵 인덱스 스캔 중간 효율적 중간

쿼리 옵티마이저의 선택

데이터베이스의 쿼리 옵티마이저는 다음과 같은 요소를 고려하여 최적의 스캔 방식을 선택합니다:

  1. 테이블 크기
  2. 인덱스 유무 및 종류
  3. 검색 조건 및 예상 결과 집합 크기
  4. 통계 정보
  5. 하드웨어 환경

비트맵 인덱스 스캔이 선택되는 조건

  1. 다수의 튜플(행)을 반환하는 경우
    • 조건에 일치하는 행이 많을 때 PostgreSQL은 일반 인덱스 스캔 대신 비트맵 스캔을 선택합니다.
    • 이유: 일반 인덱스 스캔은 행마다 랜덤 I/O를 하므로 비효율적일 수 있음. 반면 비트맵은 한 번에 페이지 단위로 처리 가능.
    
  2. OR 조건 또는 여러 조건의 조합 ``` • WHERE 절에 OR 조건, 또는 여러 인덱스를 결합해야 하는 경우 사용됩니다.

    SELECT * FROM users WHERE age = 30 OR city = 'Seoul';

• 위 쿼리는 age와 city 두 인덱스를 각각 스캔하여 비트맵으로 병합한 후, 일치하는 페이지를 읽습니다.

3. 여러 인덱스가 결합되는 경우
• PostgreSQL은 여러 인덱스를 비트맵으로 AND/OR 연산할 수 있습니다. • 이 경우 일반 인덱스 스캔은 불가능하고, 비트맵 인덱스 스캔 + 비트맵 AND/OR 전략이 사용됩니다.
4. 쿼리 비용 기반 결정 (통계/카디널리티 고려)
• PostgreSQL은 EXPLAIN 계획에서 비용 추정(cost) 을 바탕으로 인덱스 스캔 방식(일반 vs 비트맵)을 선택합니다. • 선택 기준: • 인덱스의 선택도(Selectivity) • 반환되는 예상 튜플 수 • 해당 테이블 블록 수 • 랜덤 I/O vs 순차 I/O 비용 비교 ```

결론

각 스캔 방식은 서로 다른 상황에서 최적의 성능을 제공합니다:

  • 테이블 스캔: 작은 테이블이나 대량의 데이터를 검색할 때 적합
  • 인덱스 스캔: 소량의 데이터를 검색하거나 정렬된 결과가 필요할 때 적합
  • 비트맵 인덱스 스캔: 여러 조건을 결합하거나 중간 규모의 결과 집합을 검색할 때 적합

데이터베이스 성능 최적화를 위해서는 각 스캔 방식의 특성을 이해하고, 적절한 인덱스를 설계하며, 쿼리 실행 계획을 분석하는 것이 중요합니다.