액세스 경로
액세스 방법
- 전체스캔
- 다양한 종류의 인덱스
- 해시 또는 ROWID에 의해 유도된 액세스
- 각 액세스 경로의 쓰임새는 서로 다르므로 모든 액세스 경로가 좋고 나쁨이 없이 모두 유용하다.
전체 스캔
- 데이터를 얻기위해 모든 블록을 순차적으로 읽음. 또한 멀티블록으로 읽음.
- MULTI BLOCK I/O : 오라클은 한번의 I/O 호출로 한개가 아닌 N개의 블록을 읽음.
전체스캔과 다중블록 읽기계수
- DB_FILE_MULTIBLOCK_READ_COUNT의 값을 다르게 설정할 경우 성능에 미치는 영향
- 대기 횟수 와 DB_FILE_MULTIBLOCK_READ_COUNT에 의해 나누어진 블록 수 사이에는 직접적인 상호관계가 존재한다.
- DB_FILE_MULTIBLOCK_READ_COUNT가 항상 많다가 좋은것은 아니다.
- 필자의 테스트 결과상으로는 계수가 16을 넘자 대기시간이 획기적으로 증가함 단일 블록 I/O와 다중 블록 I/O는 다르게 측정됨
- 다중 블록 읽기계수의 임계값은 운영체제와 하드웨어에 따라 결정된다
전체 스캔과 최고 수위선
- 전체스캔은 항상 세그먼트의 최고 수위선에 있는 모든 블록을 읽음
- 예) count 수가 3과 13으로 다르나, consistent gets는 419로 동일함.
- 수위선을 낮추기 위해서 테이블 복사후 다시 생성.
ROWID 액세스
- ROWID : 데이터의 물리적인 주소로, 파일에 대한 행, 블록, 그리고 블록의 행에 관한 정보를 가지고 있음.
- 특정행에 도달하는 가장 빠른 방법
!ROWID FORMAT.jpg!
- Data Object Number : DB Segmemet식별정보(해당 row가 속해있는 Object 번호)
- Relative File Number : Tablespace에 상대적인 Data file 번호(해당 row가 속해있는 데이터파일번호)
- Block Number : Row를 포함하는 Data Block번호(해당 row가 속해있는 데이터 파일의 데이터블록 주소값)
- Row Number : Block에서의 Row Slot(데이터 블록내의 해당 로우의 주소값)
ROWID 활용으로 검색속도 높이기
- 테이블의 ROWID를 정렬하여 또 다른 테이블에 넣어 독자적인 인덱스 구조를 구축하여 신속한 검색을 도모
ROWID 범위
- ROWID의 범위를 사용하면 하나의 테이블에 대한 모든 작업을 병렬로 처리가능
- (각 프로그램이 하나의 테이블에 대해서 물리적으로 뭉쳐있는 데이터에 대하여 수행되도록 보장하기 때문)
- 각 프로그램이 같은 공유 디스크 리소스로 다투지 않음.
인덱스 스캔
B*트리 구조
- Root : 인덱스의 다음 레벨을 가리키는 엔트리 포함
- Branch : 인덱스의 다음 레벨을 가리키는 엔트리 포함
- Leaf : 테이블의 행을 가리키는 인덱스 엔트리를 포함. 양방향 Linked List로 연결
Index Leaf Entry의 형식
- Entry header : 열 수와 loacking정보를 저장
- Key Column length 와 Key Column value : 키의 열길이와 열 값이 차례로 정의된 쌍으로 된 값
- ROWID : 키값을 포함한 ROWID (Leaf Block에만 ROWID저장)
인덱스 고유 스캔(Index Unique Scans)
- Unique Index에서는 데이터가 오직 인덱스키 값에 따라 정렬되어 있음.
- 예제
select *
from emp
where empno = 5000
인덱스 범위 스캔(Index Range Scans)
- 행이 하나도 반환되지 않거나 하나이상의 행이 반환될수 있다.
- 일반적으로 인덱스는 오름차순으로 데이터를 읽지만, 인덱스를 거꾸로 읽어야 할지라도 다시 정렬하거나 하지 않고 인덱스 뒤에서 부터 시작하여 읽을 수 있다.
- 예제
select *
from emp
where empno < 5000
order by empno desc
인덱스 건너뛰기 스캔(Index Skip Scans)
- 1개 이상의 컬럼이 결합되어 구성된 인덱스인 경우, 조회조건에 인덱스 대상 컬럼 중 하나가 빠졌을 경우라도 Full Scan 방식이 아닌 인덱스를 이용하여 데이터에 접근할 수 있는 방식
- 오라클 9i에서 부터 생김
인덱스 전체스캔(Index Full Scans)
- 이름이 의미하는 것과는 달리 인덱스 구조의 모든 블록을 읽지는 않는다.
- 인덱스의 모든 잎 블록을 처리하지만 첫번째 잎 블록을 찾을때 까지만 가지블록을 처리한다.
- 잎 블록은 가지블록을 통해서 도달되나, 현재의 위치가 잎 블록일 경우 포인터를 따라가기만 해도 다음블록에 도달할 수 있으므로 데이터를 앞뒤로 순회할 수 있다.
빠른 인덱스 전체 스캔(Index Fast Full Scans)
- 내부 가지블록을 포함하여 인덱스 구조의 모든 블록을 읽는다.
- 테이블 전체 스캔과 마찬가지로 다중 블록읽기를 사용한다.
- 데이터를 정렬된 순서대로 검색하지 않는다.
- 쿼리가 인덱스의 대상이 열만을 참조하고 이 인덱스에 빠른 인덱스 전체 스캔을 적용함으로써 테이블의 전체 스캔을 피할 수 있는 경우에 사용된다.
- 이런 유형의 인덱스 스캔으로부터 반환된 데이터는 정렬된 상태가 아니다.
인덱스 조인
- 쿼리에 나타난 모든 열을 포함하고 있는 테이블에 다수의 인덱스가 존재하는 경우 테이블 액세스 없이 인덱스 만으로 쿼리에 응답하는 방식
클러스터 스캔
B*트리 클러스터
- 클러스터 인덱스에 있는 클러스터 ID 정보를 통해 해당 클러스터를 찾는 작업.
- 클러스터링 테이블의 각 로우 헤더에는 클러스터키 ID를 가지고 있으므로 같은 ID를 가진 로우들을 스캔함으로써 원하는 데이터를 얻을 수 있다.
- 이 방법은 하나의 클러스터 인덱스로 여러개의 로우를 스캔방식으로 액세스할 수 있으므로 기존 인덱스보다 훨씬 적은 비용이 든다.
- 단일 클러스터 키 인덱스는 클러스터 키를 데이터베이스 블록주소로 변한하기 위해 사용
해시 클러스터
- 물리적인 인덱스를 이용하지 않고 해쉬값을 이용하여 데이터를 액세스하는 방법.
- 보조 인덱스가 존재하지 않으며 해시 키 자체가 해시 함수에 적용되어 데이터베이스 블록주소를 가리킴.
- 클러스터 액세스는 단순히 B*트리 혹은 해시 키를 취하여 이 데이터를 포함하고 있는 루트 데이터베이스 블록의 주소를 얻은다음 이 루트블록에 연결된 블록의 목록을 따라가는 절차이다.