1. 인덱스 구조
2011.02.16 22:19
1. 인덱스 구조
- 인덱스
- 정의 : 대용량 테이블에서 필요한 데이터만 빠르고 효울적 엑세스 목적의 오브젝트
- 특징 : 키 컬럼 순으로 정렬
- 범위 스캔(Range Scan)
- 정의 : 특정 위치에서 스캔을 시작하여 검색조건에 일치하지 않는 값을 만나는 순간 멈춤 (인덱스 특징 이용)
※ 참고
- 테이블 범위 스캔이 가능한 경우 : IOT(Index-Organized Table) - 특정 컬럼 순으로 정렬 상태를 유지하며 값 입력
- 일반적 힙 구조 테이블(Heap-Organized Table)은 불가능
- B*tree 인덱스 구조
- 브랜치(Branch) 블록(Root 포함) 저장 엔트리
- 키 값, 하위 노드 블록을 찾아가기 위한 DBA(Data Block Address)정보 (단, lmc에는 키 값이 없음)
※ 참고 lmc (LeftMostChild) : 키 값을 가진 첫번째 엔트리보다 작은 값, 다른 엔트리와 별도 장소 저장
- 리프(Leaf) 블록
- 인덱스 키 컬럼, 주소정보(Rowid) (정렬 우선 순위 : 1. 인덱스 키 컬럼, 2. Rowid)
- 인덱스 특징
- 리프 노드상의 인덱스 레코드와 테이블 레코드는 1:1 관계
- 리프 노드상의 키 값과 테이블 레코드 키 값 서로 일치
- 브랜치 노드상의 레코드 개수는 하위 레벨 블록 개수와 일치
- 브랜치 노드상의 키 값은 하위 노드가 갖는 값의 범위 의미
※ 참고 테이블 레코드에서 값 갱신 시,
- 리프 노드 인덱스 키 값도 같이 갱신 (delete & insert)- 브랜치 노드 값이 바뀌지는 않음 (∵ 자신의 키 값과 하위 노드 블록 포인팅 정보로 값의 범위 스캔 시 활용)
- 브랜치 노드는 인덱스 분할(Split)에 의해 새로운 블록이 추가, 삭제(다른 브랜치의 자식 노드 이동)시 갱신
- 수평적 탐색 (= 범위 스캔)
- 리프 블록을 인덱스 레코드 간 논리적 순서에 따라 좌 → 우 or 우 → 좌 스캔
- 수직적 탐색
- 수평적 탐색을 위한 시작 지점을 찾는 과정 Root → Leaf 블록 (위에서 아래쪽으로 진행)
- "CLARK"을 찾는 과정 (위의 그림 참조)
1. 루트 블록 스캔
2. 왼쪽 브랜치 or 오른쪽 브랜치 방향 결정
☞ "CLARK" 은 "KI" 보다 작기 때문에 왼쪽 브랜치블록으로 이동
3. 브랜치 블록 스캔 (다음 인덱스 블록 탐색)
☞ "CLARK" 은 "BER" 보다 크고 "FO" 보다 작으므로 두 번째 레코드 블록 주소(18000A7)로 이동
4. 리프 블록까지 이동 ( 더이상 수직적 탐색 불가능 - 탐색 결과 有 / 無 )
☞ "CLARK" 을 찾아 수평적 탐색 (= 범위 스캔) 진행
5. 인덱스 리프 블록 스캔하면서 "CLARK" 일치 확인
6. 값이 "CLARK" 인 엔트리에서 ROWID (00000B1C.001E.0004)로 해당 테이블 레코드 이동 후 필요한 다른 컬럼의 값을 읽음
※ 쿼리에서 인덱스 컬럼만 필요 시 생략
7. 5,6번 과정 반복하다 검색조건에서 벗어나는 레코드를 만나는 순간 멈춤
ⅰ. 브랜치 블록 스캔
- 브랜치 블록 스캔 시 뒤에서부터 스캔하는 방식이 유리
- 오라클이 실제로 뒤쪽부터 스캔하는지는 모름
- 교재에서 인덱스 스캔과정 설명 시 뒤쪽부터 스캔으로 가정
- 수직적 탐색 진행 시, 찾고자 하는 값보다 키 값이 작은 엔트리를 따라 내려감
※ 참고 : 뒤에서부터 스캔하는 방식이 유리한 이유
ⅱ. 결합 인덱스 구조와 탐색
- 2개 이상의 컬럼이 결합 된 인덱스
- 결합 된 컬럼 작성 순으로 스캔
※ 예시 : EMP 테이블의 결합 인덱스
- 상황 1 : ( deptno + sal ) 컬럼 순으로 생성한 결합 인덱스
- 상황 2 : deptno = 20 and sal >= 2000 조건의 쿼리
☞ 먼저 deptno 조건 체크 후 sal 의 조건 체크 (∴ 결합 인덱스에서 컬럼의 순서 중요)
(4) ROWID 포맷
- 제한 ROWID 포맷
- 대상
- 오라클 7 버전까지의 ROWID
- 파티션되지 않은 일반 테이블에 생성한 인덱스 (오라클 8i 이후)
- 파티션된 테이블에 생성한 로컬 파티션 인덱스 (오라클 8i 이후)
- 구성 ( " . " 을 포함한 18자리 문자열 )
〔 블록 번호(8) 〕.〔 로우 번호(4) 〕.〔 데이터파일 번호(4) 〕
- 확장 ROWID 포맷
- 대상
- 파티션 테이블에 생성한 글로벌 파티션 인덱스 (오라클 8i 이후)
- 파티션 테이블에 생성한 비파티션 인덱스 (오라클 8i 이후)
- 구성 (18자리 문자열)
〔 데이터 오브젝트(6) 〕〔 데이터파일 번호(3) 〕〔 블록 번호(6) 〕〔 로우 번호(3) 〕
- 오라클 고도화 원리와 해법 2 (bysql.net 2011년 1차 스터디)
- 작성자: 위충환 (실천하자)
- 최초작성일: 2011년 02월 20 일
- 본문서는 bysql.net 스터디 결과입니다 .본 문서를 인용하실때는 출처를 밝혀주세요. http://www.bysql.net
- 문서의 잘못된 점이나 질문사항은 본 문서에 댓글로 남겨주세요. ^^
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
40 | 2. 서브쿼리 Unnesting | darkbeom | 2011.05.16 | 19727 |
39 | 2. 소트를 발생시키는 오퍼레이션 | 휘휘 | 2011.06.12 | 3471 |
38 | 2. 파티션 Pruning | 실천하자 | 2011.06.22 | 26040 |
37 | 3. 병렬 조인 | 실천하자 | 2011.06.28 | 7166 |
36 | 3. 다양한 인덱스 스캔 방식 | 멋진넘 | 2011.02.19 | 33825 |
35 | 3. 해시 조인 | darkbeom | 2011.03.21 | 21545 |
34 | 3. 옵티마이저의 한계 | 멋진넘 | 2011.04.19 | 7866 |
33 | 3. 뷰 Merging | 실천하자 | 2011.05.15 | 23452 |
32 | 3. 데이터 모델 측면에서의 검토 | 멋진넘 | 2011.06.13 | 5886 |
31 | 3. 인덱스 파티셔닝 | darkbeom | 2011.06.20 | 53968 |
30 | 4. 테이블 Random 액세스 부하 [1] | darkbeom | 2011.02.24 | 14694 |
29 | 4. 조인 순서의 중요성 | 운영자 | 2011.03.28 | 14280 |
28 | 4. 통계정보 Ⅰ | darkbeom | 2011.04.26 | 18147 |
27 | 4. 조건절 Pushing | 실천하자 | 2011.05.31 | 7049 |
26 | 4. 소트가 발생하지 않도록 SQL 작성 | 멋진넘 | 2011.06.13 | 7904 |
25 | 5. 테이블 Random 액세스 최소화 튜닝 | suspace | 2011.02.25 | 6983 |
24 | 6. 스칼라 서브쿼리를 이용한 조인 [1] | 휘휘 | 2011.03.29 | 6646 |
23 | 5. Outer 조인 | 실천하자 | 2011.03.30 | 5036 |
22 | 5. 카디널리티 | suspace | 2011.04.26 | 5960 |
21 | 5. 조건절 이행 | 휘휘 | 2011.05.30 | 5427 |
새로쓴 대용량 DB 1권 중 인덱스 정보 ☞ http://bysql.net/?document_srl=6676