권순용의 DB 이야기
B*TREE 인덱스의 고려사항과 비트맵 인덱스 0 0 99,999+

by axiom B-TREE 인덱스 비트맵 인덱스 [2015.12.21]


이 글에서는 오라클 데이터베이스(DB)의 네 가지 인덱스 중 가장 광범위하게 쓰이는 B*TREE 인덱스를 사용할 때 고려해야 할 것들을 살펴본다.

B*TREE 인덱스에서 고려해야 할 것 중 하나는 랜덤 액세스의 양이다.

인덱스가 적용된 DB에서 필요한 값을 찾을 때에는 가장 먼저 테이블을 조회하게 된다. 이러한 조회 과정에서 발생하는 I/O가 랜덤 액세스이기 때문에 B*TREE 인덱스를 사용할 때에는 랜덤 액세스의 양을 특히 신경써야 한다. 만약 랜덤 액세스의 양이 지나치게 많으면 B*TREE 인덱스를 이용하지 않는 게 좋다.

  • B*TREE 인덱스의 고려사항과 비트맵 인덱스

OR 조건

OR 조건은 <그림 2>처럼 조건이 추가될 때마다 처리 대상이 계속 확대된다. 그렇기 때문에 옵티마이저는 테이블 전체 스캔(Full Scan)을 수행하는 게 유리하다고 판단한다.

그러므로 OR 조건을 사용하는 많은 경우에 B*TREE 인덱스 대신 테이블 전체 스캔으로 수행된다. B*TREE 인덱스를 스캔하더라도 OR로 인해 처리 대상 범위가 증가해 랜덤 액세스가 크게 증가하게 된다.

  • B*TREE 인덱스의 고려사항과 비트맵 인덱스

AND 조건

AND 연산은 조건이 추가될 때마다 처리 대상 집합이 감소한다. AND 연산자가 계속 추가되고 해당 조건으로 구현된 B*TREE 인덱스가 존재한다면 옵티마이저는 해당 인덱스를 이용해 SQL을 수행하게 된다.

처리 대상 집합이 감소하면 인덱스를 스캔하는 양과 랜덤 액세스도 감소하게 된다. B*TREE 인덱스는 OR 연산자의 경우 비트맵(Bitmap) 인덱스에 비해 불리하다.

OR 연산을 B*TREE 인덱스로 처리해야 한다면 경우에 따라 IN을 사용한 SQL 튜닝을 통해 최적화할 수 있다. 이처럼 B*TREE 인덱스는 해당 인덱스로 구성되는 데이터의 전체 분포도에 중요하다.

B*TREE 인덱스에서 많은 데이터를 액세스한 후 테이블을 액세스해야 할 경우 B*TREE 인덱스를 이용하면 성능 저하가 발생한다.

비트맵 인덱스의 구성 및 엑세스 확인

비트맵 인덱스는 B*TREE 인덱스와 달리 비트맵, 즉 0 또는 1로 인덱스를 관리한다. 분포도가 낮은 컬럼에 적용할 때 효과를 기대할 수 있다.

  • B*TREE 인덱스의 고려사항과 비트맵 인덱스

비트맵 인덱스의 구성

분포도가 낮은 대표적인 예는 성별 컬럼이다. 성별 컬럼은 남자, 여자 둘 중 하나의 값만을 가진다. 이러한 컬럼을 분포도가 낮다고 말한다. 이런 컬럼은 B*TREE 인덱스보다는 비트맵 인덱스를 이용하는 게 액세스 성능 측면에서 더 유리하다.

  • [그림 4] 이미지가 없네요

<그림 4>의 비트맵 인덱스를 살펴보자. 기본 구조는 B*TREE 인덱스와 유사하다. 루트 블록과 브랜치 블록은 B*TREE 인덱스와 동일하며 다른 부분은 리프 블록에 저장되는 인덱스 엔트리다.

B*TREE 인덱스는 < 인덱스 Key, ROWID>가 인덱스 엔트리에 저장됐지만 비트맵 인덱스는 해당 인덱스 컬럼에 대한 비트맵이 <그림 4>처럼 저장된다.

<그림 4> 비트맵 인덱스의 리프 블록을 확인해보면 컬럼 값 또는 Key, Start ROWID, End ROWID, 비트맵으로 구성돼 있다.

  • - 컬럼 값 : 성별 컬럼이므로 남자, 여자 두 가지의 컬럼 값이 저장된다.
  • - Start ROWID : 해당 테이블의 시작 ROWID
  • - End ROWID : 해당 테이블의 마지막 ROWID
  • - 비트맵 : 해당되는 데이터가 남자면 남자 비트맵에 1을, 여자 비트맵(Bitmap)에는 0을 부여한다.

비트맵 인덱스는 이처럼 해당 값을 비트맵으로 구성해 리프 블록을 생선한다. 비트맵 인덱스의 구조에 대해 좀 더 자세히 살펴보자.

  • [그림 5]
  • B*TREE 인덱스의 고려사항과 비트맵 인덱스

<그림 5>에서 이가혜라는 데이터는 여자이므로 남자 비트맵에는 0을 저장하고, 여자 비트맵에는 1을 저장한다. 그 결과, 남자 비트맵의 비트 값은 010111, 여자 비트맵의 비트 값은 101000이 된다.

남자 비트맵과 여자 비트맵을 서로 비교하면, 첫 번째 데이터는 여자이고, 두 번째 데이터는 남자다. 세 번째느 여자인 것을 확인할 수 있다. 그렇기 때문에 모든 비트맵을 조합하면 어떤 값을 저장하는지 알 수 있다.

비트맵 인덱스의 액세스

지금부터는 비트맵 인덱스를 이용한 데이터 액세스를 확인해보자.

  • [리스트 1] SQL 예
  •  SELECT 이름, 주소 
       FROM 고객
      WHERE 성별='여자';
    

<그림 5>의 고객 테이블은 대용량 테이블이며 성별에 비트맵 인덱스가 적용돼 있다고 가정하자. <리스트 1> SQL은 과연 어떤 과정을 거쳐 데이터에 액세스할까?

① 성별이 여자라는 조건을 설정했기 때문에 성별 비트맵 인덱스의 리프 블록의 비트맵 중 여자 비트맵을 액세스하게 된다.

② 1 단계에 의해 101000이라는 여자 비트맵(Bitmap)을 액세스한다.

③ 해당 비트맵만 추출하면 몇 번째 데이터가 여자인지를 알 수 있다. 이 케이스의 경우 해당 테이블의 첫 번째와 세 번째 데이터가 성별이 여자인 데이터다.

④ 해당 테이블의 Start ROWID와 End ROWID를 이용해 첫번째 데이터와 세번째 데이터의 ROWID를 생성한다.

⑤ 4 단계에서의 ROWID를 이용해 고객 테이블을 액세스함으로써 결과를 추출한다.

이러한 과정으로 비트맵 인덱스를 액세스해 데이터를 추출하게 된다.

참고링크

- 강좌 URL : http://www.gurubee.net/lecture/2957

- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^

- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입