4. Block
Block 구조
- INSERT 시 순서는 보장하지 않는다.
- Condensing(재배치)
: 하나의 ROW가 끊어지지 않고 들어갈 수
있는 이어진 공간을 만들기 위한 작업
- FREE SPACE는 새로운 ROW가 사용하는
공간이 아니라, 이미 들어가 있는 ROW의
길이가 변경되면 사용한다.
5. Index - 용어
- RowID: Object No + Datafile No + Block No
+ Slot No (단, Slot No는 상대경로)
- Tablespace: 논리적인 저장공간, 물리적인
데이터 파일(datafile)로 구성됨
- Segment: tablespace를 나눈 개념. data
object가 들어올 수 있게 함
- Fragmentation: 단편화. C++과 동일.
- Row Migration: Row가 다른 블록으로 이주
할 때, 삭제 후 삽입을 하지 않고 이전 주소에
다음 주소를 적어놓고 이동하는 개념.
- Chain: 하나의 블록 크기보다 큰 로우를 저장
할 때, 블록을 연결하는 개념
6. ● 액세스 순서 (select)
1. 인덱스 테이블에서 RowID를 찾아낸다.
( B-Tree Search )
2. RowID의 Object No, DataFile No, Block
No를 통해 해당 블록을 접근한다.
3. 마지막 Slot No를 통해 해당 컬럼 값의 데이
터에 접근한다.
● 데이터 이동의 특징
- 자주 발생하면 Fragmentation.
- Slot 내의 이동은 비교적 간단하다.
Index - 특징
7. Clustering Factor
: Index Row와 Data Row의 정렬 정도를 의미. (= 액세스 효율)
Index부터 Block 까지는 논리적인 정보이다. tree 형식이라면 정렬이 되어 있을 것.
그러나 slot은 삭제->삽입의 작업이 지속적으로 일어나면 정렬이 랜덤하게 깨지게 된다.
결국 액세스 효율은 Slot No의 정렬 정도라고도 할 수 있다.
8. Clustering Factor 향상 전략
- 데이터 저장형식에 강제적인 제약 없이 임의의 위치에 저장하는 방식
(삽입 보통, 액세스 효율 보통: 물론 케바케)
- 저장 시의 약간의 추가적인 비용이 들어가더라도 우리가 원하는 형태로 데이터를 저장하는 방식
(삽입 느림, 액세스 빠름)
- 주기적으로 테이블을 재생성하는 방법
(추가적인 부하 생김. 액세스는 재생성후 가장 빠름)
● 용어
- Differed write (지연 기록)
: 데이터 처리를 메모리 내에서만 처리하고 최종 목적지인 디스크에는 여유가 있을 때에 옮겨두는 방
9. 예시) 대형 테이블
- 단순 저장형 개념(log)
: 특정 액세스 형태로 읽거나, 대량을 스캔하는 형태로 주요 사용, 신속한 저장이 요구됨. 분리형이 가
장 적절하다.
- 대량의 데이터가 있지만, 랜덤 액세스가 주로 일어나며 다양한 액세스 형태를
갖지 않는 경우(고객 테이블)
: 분리형 구조가 적절. 대량의 데이터가 들어오거나, 범위처리를 자주 하지도 않음.
- 대량의 데이터가 계속 증가, 다양한 액세스 형태를 갖는 경우(매출 테이블)
: 파티션 적용이 바람직, 어떻게 최소한의 필요한 부분만 액세스를 할 것인가에 대한 고민을 해야함.
인덱스 전략 후 실행계획을 최적화 시크는 방법이 중요.가장 중요한 것은 테이블 구조를 어떻게 결정
하느냐에 따라 달려있다.
11. 인덱스 일체형 테이블?
: 테이블과 인덱스가 일체형으로 되어있는 형태.
물리적으로 모두같은 위치에 저장되는 형태를 말한다.
● 질의가 기본키를 스캔하고, 기본키의 길이가 row에서 높은 비율을 차지한다면
효율적임.
● 그러나, 랜덤 액세스 시 최악의 경우는 매번 새로운 블록을 액세스 할 수도 있
다.
13. 구조와 특징
장점1: 인덱스를 경유하지 않기 때문에 한 번의 논리적 액세스가 줄어든다.
장점2: 넓은 범위의 인덱스 스캔은 분리형에 비해 부담이 적다.
단점1: 인덱스에 모든 컬럼이 함께 저장되기 때문에 인덱스 입장에서만 생각하면
훨씬 많은 블록에 퍼져있게 된다.
단점2: 추가 인덱스 생성이 어렵다. (RowID가 없기 때문에 항상 기본키를 써야함.)
=> 기본키 액세스가 RowID로 액세스 하는 것보다 훨씬 불리하다. // 왜?
단점3: Row의 길이 변화에 따라 발생할 수 있는 오버플로우(확률 높음)
14. RowID의 부재
일체형 테이블은 b-tree 인덱스의 리프노드(leaf node)에 데이터를 함께 저장하는
구조를 가지고 있다. 데이터가 증가함에 따라 트리가 성장하고 키 값을 가지고 있는
노드가 분할하게 될 때 어떤 키값이 동일한 노드에 지속적으로 저장되어 있을 수 없
다.
=>영구적인 물리주소를 가질 수 없다.
=>rowid를 근거로 하여 row들을 인식할 수 없다.
=>기본키만 데이터를 구분할 수 있는 유일한 방법이 된다.
● 인덱스의 병합이 분할보다 부하가 크기 때문에, 인덱스의 병합을 수행하지 않
고 기존 인덱스 구조를 유지하도록 하고 있다. 그로인해 트리는 성장만을 지속
하게 되고, 데이터를 전부 삭제하여도 인덱스 구조는 그대로 유지된다.
-> index rebuild가 필요하게 됨
15. 논리적 RowID와 Physical Guess
논리적 RowID:
이 주소는 인덱스 로우가 생성될 때 만들어져서 키 분할에 의해 데이터 블록의 위
치가 달라져도 변경되지 않는다.
Physical Guess:
물리적인 주소를 나타낸다고 하기보다는 그 로우가 존재할 가능성이 높은 주소를
나타낸다.
데이터 액세스 시 만약 이 값이 부정확한 값이라고 판명되면 그때는 기본키를 이용
한 액세스를 진행한다.
또 physical guess가 부정확할 확률이 높다고 판단되면 아예 이것으로 액세스를 시
도하지도 않는다.
16. 액세스 수행 절차
● 물리적 위치정보를 사용하지 않는 경우
1. 추가적인 인덱스를 액세스 하여 기본키 정보를 얻는다.
2. 기본키로 데이터 블록을 액세스 한다.
● 물리적 위치정보를 사용하는 경우
1. 추가적인 인덱스를 액세스하여 물리적 위치정보를 참조한다.
2. 참조한 물리적 위치정보를 이용하여 데이터 블록을 액세스한 후에 비교한다. 이때 기본키 값이
같으면 물리적 위치 정보가 유효한 것으로 간주하여 액세스를 종료한다.
3. 만약 유요하지 않다면 다시 기본키로 액세스하여 데이터 블록을 가져온다.
● 정리
: 물리적 위치정보가 정확하다면 일반적인 인덱스 스캔과 동일, 적중률이 낮다면 오히려 기본키를 사
용하는 것이 더 효율적이다.
리빌드도 쉽지않다. (인덱스만 액세스 하지 않고, 풀스캔 해야하기 때문에)
17. Overflow Area
: 적재할 컬럼을 줄이는 방법, 상대적으로 빈번하게 액세스 되지 않는 것들을 미리
오버플로우 영역에 옮겨두는것.
일체형 테이블을 생성할 때 이동에 대한 임계치 (PCTTHRESHOLD)에 도달하면
'including'절에서 지정한 컬럼 이후의 컬럼들은 모두 오버플로우 영역에 저장된다.
=> 컬럼 순서도 중요
일체형 구조의 본체는 인덱스 세그먼트에 저장됨. 오버플로우 영역은 테이블 세그
먼트에 생성됨. 인덱스 영역에는 오버플로우 영역의 rowid를 가지게 된다.
18. 더 찾아봐야 할 내용(고민거리)
- LONG, LONG RAW, LOB의 개념
- 인덱스의 병합이 분할보다 부하(데이터 이동)가 크다는데 왜 그럴까?
// 요건 뒤에 B-Tree에 자세히 나오네요. 일단 pass
19. - 새로쓴 대용량 데이터베이스 솔루션
- http://wiki.gurubee.net/pages/viewpage.action?pageId=12714017
// 구루비 스터디 페이지
- https://www.cs.usfca.edu/~galles/visualization/BTree.html
// visualization of tree algorithm
References
20. 모르는 것 찾아보기
- 인덱스를 계속 사용할 때, branch depth가 왜 증가하고, 정리하면 왜 줄어드는지?
// 이것도 뒤에.. 결론만 말하면 “분할과 삭제” 동작에서 빈 공간이 생겨서 block수
가 늘어납니다.
- free space의 종류.
PCTFREE: 새로 할당할 때 사용하는 공간이 아니라, row의 길이가 변경될 때를
대비하여 남겨두는 공간.
총 블럭크기-PCTFREE => 새로운 row가 저장될 수 있는 가용 크기
- log table 분리형/일체형 적합여부 => 분리형 테이블