Post

Index 기본1

#naver-import

원문: https://blog.naver.com/qoxmfaktmxj/222881950713

인덱스는 대용량 테이블에서 필요한 데이터만 빠르게 효율적으로 액세스하기 위해 사용하는 오브젝트

(모든 책 뒤쪽에 있는 색인과 같은 역할)

인덱스 없이는 처음부터 끝까지 탐색하지만 인덱스 활용 시 일부만 읽고 멈추는 범위스캔(Range Scan)이 가능하다. = 인덱스가 정렬되어 있기 때문

DBMS -> B Tree 구조 : Root에서 Leaf까지

1.루트, 브랜치 블록의 있는 각 레코드는 하위 블록에 대한 주소값 갖음

2.가장 왼쪽 레코드는 LMC (Leftmost Child) 로 키값을 갖지 않는 특별한 레코드로 자식 노드 중 가장 왼쪽 끝에 위치

3.리프 블록에 저장된 레코드는 키값 순으로 정렬

4.리프 블록에 저장된 레코드는 ROWID 값을 가지고 인덱스 키 값이 같으면 ROWID 순으로 정렬

=인덱스 스캔의 이유는 검색 조건을 만족하는 소량의 데이터를 빨리 찾고 거기서 ROWID를 얻기 위해서이다.

ROWID = 데이터 블록 주소( Data Block Address, DBA) + 로우 번호

데이터 블록 주소 = 데이터 파일 번호 + 블록 번호

블록 번호 : 데이터 파일 내에서 부여한 상대적 순번

로우 번호 : 블록 내 순번

수직적 탐색 - 인덱스 스캔 시작지점을 찾는 과정

수직적 탐색은 조건을 만족하는 레코드를 찾는 과정이 아닌 조건을 만족하는 첫번째 레코드를 찾는 과정이다

수평적 탐색 - 데이터 찾는 과정

수직적 탐색으로 스캔 시작점을 찾은 후 찾고자 하는 데이터가 더 안나타날 때까지 인덱스 리프 블록을 수평적으로 스캔하는 과정

인덱스 리프 블록끼리는 앞뒤 블록에 대한 주소값을 갖는 양방향 연결 리스트라 수평적 탐색 가능

인덱스를 수평적 탐색하는 이유

1.조건절을 만족하는 데이터를 모두 찾기 위함

2.ROWID 얻기 위함

(필요한 컬럼을 인덱스가 모두 갖고 있어 인덱스만 스캔하고 끝나는 경우도 있지만, 일반적으로 인덱스 스캔 -> 테이블 액세스 한다. 이 때 ROWID가 필요함)

인덱스 구성 시 (고객명 + 성별, 성별+고객명) 둘 다 읽는 인덱스 블록 갯수가 같다.

-> 인덱스 선두 컬럼을 모두 = 조건으로 검색하면 어느 컬럼을 인덱스 앞쪽에 두든 블록 I/O 갯수가 같으므로 성능이 같다.

결합 인덱스 구성 차이?

select 이름, 성별 from 사원 where 성별 = ‘여자’ and 이름 = ‘유관순’

1. 인덱스를 (성별+이름)순으로 구성한 경우 총 사원 50명 가정, 50명에서 성별 = ‘여자’인 레코드 25건을 찾고, 거기서 이름을 검사해 최종적으로 2명 출력 ->25번의 검사

2.인덱스를 (이름+성별)순응로 구성한 경우 총 사원 50명 중에서 이름 = ‘유관순’인 레코드 2건을 찾고, 거기서 성별을 검사해 최종적으로 2명 출력 ->2번의 검사 ?????

선택도가 낮은 ‘이름’ 컬럼을 앞쪽에 두고 결합인덱스를 생성해야 검사 횟수를 줄일 수 있어 성능에 유리하다고 할 수 있지만, 위 설명과 같이 DBMS가 엑셀처럼 필터링을 하지는 않는다.


DBMS가 사용하는 B Tree 인덱스는 엑셀처럼 평면 구조가 아니기 떄문에 (다단계 구조) 위와 같이 탐색할 시 루트에서 브랜치를 거쳐 리프 블록까지 탐색하면서 ‘여자’이면서 ‘유관순’인 첫 번쨰 사원 찾아간다.

거기서 부터 두건을 스캔하게 된다. 정확히 따져보면 유관순이 아닌 레코드까지 세 건을 스캔한다. 인덱스를 이름 +성별 성별 +이름 어느 컬럼을 앞에 두어도 일량에는 차이가 없다.

따라서, 선택도가 낮은 “이름” 컬럼을 앞쪽에 두고 결합인덱스를 생성해야 검사횟수 줄일 수 있어 성능에 유리하다 => 틀린말이다

인덱스를 [성별 + 이름]으로 하든 [이름+성별] 로 하든 읽는 인덱스 블록 개수가 똑같다. 인덱스를 어떻게 구성하든 블록 I/O개수가 같다면 성능도 같다.

위 예제에서 비교 연산 횟수가 줄어드는 건 사실이지만 성능에서 차이는 없다. 인덱스 구성에 따라 성능의 차이가 나는 것은 있지만, 그것은 위의 글 같은 이유는 아니다.


참고 : B Tree Index의 B 는 Balanced의 약자이다.

Balanced는 어떤 값으로 탐색하더라도 인덱스 루트에서 리프 블록에 도달하기까지 읽는 블록수가 같음을 의미한다. 즉, 루트로부터 모든 리프 블록까지 높이는 항상 같다는 말

  • 따라서 delete등의 작업 때문에 Index가 불균형 상태에 놓이는 경우는 없다.


댓글