이것저것

친절한 SQL 튜닝 - 2.1 인덱스 구조 및 탐색 본문

친절한 SQL 튜닝

친절한 SQL 튜닝 - 2.1 인덱스 구조 및 탐색

nays111 2021. 3. 9. 22:57


2.1.2 인덱스 구조

인덱스를 사용하면 전체 테이블 스캔 필요없이 범위 스캔(range scan) 가능하다.

범위 스캔이 가능한 이유는 인덱스는 항상 정렬돼 있기 때문이다.

 

DBMS는 일반적으로 B+Tree 인덱스 사용한다. (루트+브랜치+리프)

루트와 브랜치 블록에는 키 값을 갖지 않는 특별한 레코드 존재한다. (이를 LMC라고 부른다.)

LMC : 자식 노드 중 가장 왼쪽 끝에 위치한 블록

리프 블록에 저장된 각 레코드는 키값 순으로 정렬되어있고, ROWID (테이블 레코드를 가리키는 주소값)을 가짐

  • 인덱스 키 값이 같을시 ROWID 순으로 정렬

2.1.3 인덱스 수직적 탐색, 2.1.4 인덱스 수평적 탐색

인덱스 탐색 과정

(1) 수직적 탐색 : 인덱스 스캔 시작지점을 찾는 과정

가장 처음에 인덱스 스캔 시작지점을 찾는다.

루트 블록에서 시작 (루트를 포함해 브랜치 블록에 저장된 각 인덱스 레코드는 하위 블록에 대한 주소값을 가짐)

"조건을 만족하는 첫 번째 레코드"가 목표지점

 

(2) 수평적 탐색 : 데이터를 찾는 과정

리프 블록끼리는 쌍방향 연결리스트 구조 (좌-> 우, 우->좌 로 탐색 가능)

수평적으로 탐색하는  2가지 이유?

  1. 조건절을 만족하는 데이터를 모두 찾기 위해
  2. ROWID를 얻기 위해 (만약 필요한 컬럼을 인덱스가 모두 갖고있다면 인덱스 스캔만 하지만 일반적으로 인덱스를 스캔하고서 테이블도 액세스한다. 이때 ROWID가 필요)

2.1.5 결합 인덱스 구조와 탐색

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

1. 인덱스를 [성별 + 이름] 순으로 구성한 경우

총 사원 50명 중에서 성별 = ‘여자’인 레코드 25건을 찾고, 거기서 이름을 검사해 최종적으로 2명 출력

  • 25번의 검사

2. 인덱스를 [이름 + 성별] 순으로 구성한 경우

총 사원 50명 중에서 이름 = ‘유관순'인 레코드 2건을 찾고, 거기서 성별을 검사해 최종적으로 2명 출력

  • 2번의 검사

선택도가 낮은 "이름" 컬럼을 앞쪽에 두고 결합인덱스를 생성해야 검사횟수 줄일 수 있어 성능에 유리하다

=> 틀린말이다

인덱스를 [성별 + 이름]으로 하든 [이름+성별] 로 하든 읽는 인덱스 블록 개수가 똑같다.

인덱스를 어떻게 구성하든 블록 I/O개수가 같다면 성능도 같다.

위 예제에서 비교 연산 횟수가 줄어드는 건 사실이지만 성능에서 차이는 없다.

Comments