Oracle/Administration2018. 10. 9. 09:37

인덱스 브랜치 블록의 로우는 리프 블록을 분기하기 위한 고유한 값을 가져야 한다. 고유하기만 하면 전체 칼럼 값을 저장하지 않아도 된다.


테스트를 위해 아래와 같이 테이블을 생성하자. ROWID가 칼럼으로 저장되는 NON-UNIQUE 인덱스(t1_x1)를 생성했다.

-- 1
DROP TABLE t1 PURGE;
CREATE TABLE t1 AS SELECT MOD (ROWNUM, 100) AS c1, LPAD ('X', 100, 'X') AS c2 FROM XMLTABLE ('1 to 10000');
CREATE INDEX t1_x1 ON t1 (c1);

ALTER SYSTEM CHECKPOINT;

*_OBJECTS 뷰에서 오브젝트 ID를 확인하자.

-- 2-1
SELECT object_id FROM user_objects WHERE object_name = 'T1_X1';

OBJECT_ID
---------
   237780

1개의 행이 선택되었습니다.

아래 구문으로 인덱스 트리를 덤프할 수 있다.

-- 2-2
ALTER SESSION SET TRACEFILE_IDENTIFIER = 'treedump';
ALTER SESSION SET EVENTS 'immediate trace name treedump level 237780';

아래는 인덱스 트리 덤프의 내용이다. 브랜치 블록의 DBA(Data Block Address)가 29494955, 두 번째 리프 블록의 DBA가 29494957인 것을 확인할 수 있다.

-- 2-3
----- begin tree dump
branch: 0x1c20eab 29494955 (0: nrow: 20, level: 1)
   leaf: 0x1c20eac 29494956 (-1: row:520.520 avs:820)
   leaf: 0x1c20ead 29494957 (0: row:513.513 avs:818)
   leaf: 0x1c20eae 29494958 (1: row:513.513 avs:818)
   leaf: 0x1c20eaf 29494959 (2: row:513.513 avs:818)
...
----- end tree dump

DBMS_UTILITY 패키지을 통해 DBA로부터 파일 번호와 블록 번호를 추출할 수 있다.

-- 3-1
SELECT DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE  (29494955) AS branch_f
     , DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK (29494955) AS branch_b
     , DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE  (29494957) AS leaf_0_f
     , DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK (29494957) AS leaf_0_b
     , DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE  (29494958) AS leaf_1_f
     , DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK (29494958) AS leaf_1_b
     , DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE  (29494959) AS leaf_2_f
     , DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK (29494959) AS leaf_2_b
  FROM DUAL;

BRANCH_F BRANCH_B LEAF_0_F LEAF_0_B LEAF_1_F LEAF_1_B LEAF_2_F LEAF_2_B
-------- -------- -------- -------- -------- -------- -------- --------
       7   134827        7   134829        7   134830        7   134831

1개의 행이 선택되었습니다.

아래 구문으로 인덱스 블록을 덤프할 수 있다. 브랜치 브록과 두 번째, 세 번째, 네 번째 리프 블록을 덤프했다.

-- 3-2
ALTER SESSION SET TRACEFILE_IDENTIFIER = 'branch';
ALTER SYSTEM DUMP DATAFILE 7 BLOCK 134827;

ALTER SESSION SET TRACEFILE_IDENTIFIER = 'leaf_0';
ALTER SYSTEM DUMP DATAFILE 7 BLOCK 134829;

ALTER SESSION SET TRACEFILE_IDENTIFIER = 'leaf_1';
ALTER SYSTEM DUMP DATAFILE 7 BLOCK 134830;

ALTER SESSION SET TRACEFILE_IDENTIFIER = 'leaf_2';
ALTER SYSTEM DUMP DATAFILE 7 BLOCK 134831;

아래는 브랜치 블록의 덤프 내용이다. col 1에 ROWID의 일부 값(4자리)이 저장된 것을 확인할 수 있다. 일부 값으로도 리프 블록을 분기할 수 있기 때문에 굳이 전체 값을 저장해 불필요한 공간을 낭비하지 않은 것이다.

-- 3-3 : branch
Branch block dump
=================
row#0[8048] dba: 29494957=0x1c20ead
col 0; len 2; (2):  c1 06
col 1; len 4; (4):  01 c2 0c fb -- leaf_0 row#0의 col 1 값(01 c2 0c fb 00 18)보다 작다
row#1[8036] dba: 29494958=0x1c20eae
col 0; len 2; (2):  c1 0b
col 1; len 4; (4):  01 c2 0d e0 -- leaf_1 row#0의 col 1 값(01 c2 0d e0 00 09)보다 작다
row#2[8024] dba: 29494959=0x1c20eaf
col 0; len 2; (2):  c1 10
col 1; len 4; (4):  01 c2 0d f4 -- leaf_2 row#0의 col 1 값(01 c2 0d f4 00 3c)보다 작다
...

아래는 리프 블록의 덤프 내용이다. 두 번째 리프 블록 row#0의 col 1 값(01 c2 0c fb 00 18)이 브랜치 블록 row#0의 col1 값(01 c2 0c fb)보다 크다.

-- 3-4 : leaf_0
Leaf block dump
===============
row#0[8024] flag: -------, lock: 0, len=12
col 0; len 2; (2):  c1 06
col 1; len 6; (6):  01 c2 0c fb 00 18 -- 브랜치 row#0의 col 1 값(01 c2 0c fb)보다 크다
...

-- 3-5 : leaf_1
Leaf block dump
===============
row#0[8024] flag: -------, lock: 0, len=12
col 0; len 2; (2):  c1 0b
col 1; len 6; (6):  01 c2 0d e0 00 09 -- 브랜치 row#1의 col 1 값(01 c2 0d e0)보다 크다
...

-- 3-6 : leaf_2
Leaf block dump
===============
row#0[8024] flag: -------, lock: 0, len=12
col 0; len 2; (2):  c1 10
col 1; len 6; (6):  01 c2 0d f4 00 3c -- 브랜치 row#2의 col 1 값(01 c2 0d f4)보다 크다
...


'Oracle > Administration' 카테고리의 다른 글

CHAR(1) vs VARCHAR2(1)  (0) 2018.10.17
히든 파라미터 조회 뷰 생성  (0) 2018.10.16
Online Statistics Gathering for Bulk Loads  (0) 2018.09.29
CLOB #4 - EMPTY_CLOB 함수  (0) 2018.07.12
CLOB #3 - LONGCHUNKSIZE  (0) 2018.06.23
Posted by 정희락_