프린트 하기

내맘대로긍정이 알려주는

Oracle 23ai 신기능
무료 세미나 발표자료

다운로드 trending_flat

OS환경 : Oracle Linux 7.6 (64bit)

 

DB 환경 : Oracle Database 19.3.0.0

 

방법 : 오라클 19c 인덱스 생성시 nosort 옵션(assm 환경)

오라클 문서를 보던중 인덱스 생성시 nosort 라는 옵션을 발견하여 몇가지 테스트해봄

이 옵션은 인덱스 생성 시 정렬작업을 생략하는 명령어임(인덱스 생성시 기본값은 sort 이고 nosort 가 옵션임)
기본적으로 인덱스는 정렬된 구조로 되어있는데 어떻게 정렬을 생략하면서 인덱스를 만들수 있는지 의문이 들수있음
이 옵션은 무조건 정렬를 하지 않는것이 아닌 인덱스를 만드려는 컬럼이 정렬된 상태로 존재 할 때 정렬을 생략하는 옵션임

 

 

실제로 정렬이 된 상태로 nosort 옵션과 함께 인덱스를 만들면 인덱스가 정상적으로 생성이 되고
정렬이 되지 않은 상태로 nosort 옵션과 함께 인덱스를 만들면 ORA-01409 에러가 발생함
그리고 블록의 순서대로(rowid를 결정함) 데이터가 들어가 있지 않으면 nosort 옵션 사용시 에러가 발생함
그리고 여러 익스텐트에 걸쳐 데이터가 존재하는 경우 두 번째 익스텐트의 첫 번째 블록의 dba(data block address)가
첫 번째 익스텐트의 마지막 dba(data block address)보다 작은 경우에도 nosort 옵션 사용시 에러가 발생함

 

 

nosort 옵션 제약조건 정리
- REVERSE 옵션과 같이 사용불가
- 파티션 클러스터 인덱스 또는 비트맵 인덱스를 생성 불가
- IOT 테이블에 secondary index로 사용불가
- 테이블 데이터가 정렬(rowid 순으로)이 되어있지 않으면 사용 불가
- 여러 익스텐트에 걸쳐 데이터가 존재하는 경우 두 번째 익스텐트의 첫 번째 블록의 dba가 첫 번째 익스텐트의 마지막 dba보다 작은 경우 사용 불가

 

 

이렇게 제약조건이 많아서 실제 업무에선 사용하기 어려울수 있지만
이 제약조건을 피해서 인덱스를 생성 하는 경우 정렬하는 시간을 아낄수 있어 시간을 절약할 수 있음

 

 

assm 환경과 mssm 환경에서의 테스트 결과가 달라 2가지 모두 테스트해봄
먼저 본문은 assm 환경에서 nosort 옵션을 이용해 인덱스를 생성 했을시 시간이 얼마나 절약 되는지와 플랜 등을 확인해봄

 

 

테스트1. 일반 insert 구문으로 삽입된 소량 데이터
테스트2. ctas 구문으로 생성된 데이터
테스트3. 10046 트레이스로 플랜 확인

 

 

초기 환경 구성
샘플 테이블스페이스 생성

1
2
3
4
5
6
7
8
9
SQL> 
drop tablespace noso including contents and datafiles;
create tablespace noso datafile '/ORA19/app/oracle/oradata/ORACLE19/noso01.dbf' size 100m;
 
Tablespace created.
 
SQL> alter user imsi quota unlimited on noso;
 
User altered.

 

 

테스트1. 일반 insert 구문으로 삽입된 소량 데이터
샘플 테이블1 생성

1
2
3
4
5
6
SQL> 
conn imsi/imsi
drop table sort1 purge;
create table sort1 (col1 number) tablespace noso;
 
Table created.

 

 

sort1 테이블에 1980개 row 입력

1
2
3
4
5
6
7
8
9
10
11
12
SQL>
DECLARE
    i NUMBER := 1;
BEGIN
    FOR i IN 1..1980 LOOP
        INSERT INTO sort1 (col1) VALUES (i);
    END LOOP;
    COMMIT;
END;
/
 
PL/SQL procedure successfully completed.

 

 

extent, block 확인

1
2
3
4
5
6
7
8
SQL>
select extent_id, file_id, block_id, blocks, bytes
from dba_extents
where segment_name = 'SORT1';
 
 EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS      BYTES
---------- ---------- ---------- ---------- ----------
         0          7        128          8      65536

1개 extent에 블록 8개가 존재함(두번쨰 extent가 할당된건 아님)

 

 

블록 헤더 확인

1
2
3
4
5
6
7
8
9
SQL>
col segment_name for a10
select segment_name, header_file, header_block, blocks
from dba_segments
where segment_name = 'SORT1';
 
SEGMENT_NA HEADER_FILE HEADER_BLOCK     BLOCKS
---------- ----------- ------------ ----------
SORT1                7          130          8

 

 

sort1 테이블에 인덱스 생성(nosort)

1
2
3
SQL> create index sort1_ix01 on sort1(col1) nosort;
 
Index created.

정상적으로 생성됨

 

 

sort1 테이블 블록별 row 갯수 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SQL>
set lines 200 pages 1000
select
dbms_rowid.rowid_block_number(rowid) blockno,
count(rowid)
from sort1
group by dbms_rowid.rowid_block_number(rowid)
order by 1;
 
   BLOCKNO COUNT(ROWID)
---------- ------------
       132          660
       133          660
       134          660

하나의 블록당 660개 row가 들어감

 

 

sort1 테이블의 각 row별 file_id, block_id, rowid 확인(rowid 순으로 정렬해서 확인)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
SQL> 
set lines 200 pages 1000
select
dbms_rowid.rowid_relative_fno(rowid) rel_fno,
dbms_rowid.rowid_block_number(rowid) blockno,
rowid, 
col1
from sort1
order by rowid;
 
   REL_FNO    BLOCKNO ROWID                    COL1
---------- ---------- ------------------ ----------
         7        132 AAAGPPAAHAAAACEAAA          1
         7        132 AAAGPPAAHAAAACEAAB          2
         7        132 AAAGPPAAHAAAACEAAC          3
         7        132 AAAGPPAAHAAAACEAAD          4
.
.
         7        134 AAAGPPAAHAAAACGAKQ       1977
         7        134 AAAGPPAAHAAAACGAKR       1978
         7        134 AAAGPPAAHAAAACGAKS       1979
         7        134 AAAGPPAAHAAAACGAKT       1980
 
1980 rows selected.

col1 컬럼과 rowid가 순서대로 정렬되어있음

 

 

샘플 테이블2 생성

1
2
3
4
5
SQL> 
drop table sort2 purge;
create table sort2 (col1 number) tablespace noso;
 
Table created.

 

 

sort2 테이블에 1981개 row 입력

1
2
3
4
5
6
7
8
9
10
SQL>
DECLARE
    i NUMBER := 1;
BEGIN
    FOR i IN 1..1981 LOOP
        INSERT INTO sort2 (col1) VALUES (i);
    END LOOP;
    COMMIT;
END;
/

 

 

extent, block 확인

1
2
3
4
5
6
7
8
SQL>
select extent_id, file_id, block_id, blocks, bytes
from dba_extents
where segment_name = 'SORT2';
 
 EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS      BYTES
---------- ---------- ---------- ---------- ----------
         0          7        136          8      65536

1개 extent에 블록 8개가 존재함(두번쨰 extent가 할당된건 아님)

 

 

블록 헤더 확인

1
2
3
4
5
6
7
8
9
SQL>
col segment_name for a10
select segment_name, header_file, header_block, blocks
from dba_segments
where segment_name = 'SORT2';
 
SEGMENT_NA HEADER_FILE HEADER_BLOCK     BLOCKS
---------- ----------- ------------ ----------
SORT2                7          138          8

 

 

sort2 테이블에 인덱스 생성(nosort)

1
2
3
SQL> create index sort2_ix01 on sort2(col1) nosort;
 
Index created.

정상적으로 생성됨

 

 

sort2 테이블의 각 row별 file_id, block_id, rowid 확인(rowid 순으로 정렬해서 확인)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
SQL> 
set lines 200 pages 1000
select
dbms_rowid.rowid_relative_fno(rowid) rel_fno,
dbms_rowid.rowid_block_number(rowid) blockno,
rowid, 
col1
from sort2
order by rowid;
 
   REL_FNO    BLOCKNO ROWID                    COL1
---------- ---------- ------------------ ----------
         7        140 AAAGPRAAHAAAACMAAA          1
         7        140 AAAGPRAAHAAAACMAAB          2
         7        140 AAAGPRAAHAAAACMAAC          3
         7        140 AAAGPRAAHAAAACMAAD          4
 
.
.
         7        142 AAAGPRAAHAAAACOAKR       1978
         7        142 AAAGPRAAHAAAACOAKS       1979
         7        142 AAAGPRAAHAAAACOAKT       1980
         7        143 AAAGPRAAHAAAACPAAA       1981
 
1981 rows selected.

col1 컬럼과 rowid가 순서대로 정렬되어있음
1981번쨰 데이터도 143번쨰 블록에 순서대로 들어가있음

 

 

sort2 테이블 블록별 row 갯수 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SQL>
set lines 200 pages 1000
select
dbms_rowid.rowid_block_number(rowid) blockno,
count(rowid)
from sort2
group by dbms_rowid.rowid_block_number(rowid)
order by 1;
 
   BLOCKNO COUNT(ROWID)
---------- ------------
       140          660
       141          660
       142          660
       143            1

하나의 블록당 660개 row가 들어감
1981번째 데이터는 143번 블록에 삽입됨

 

 

새 블록을 할당 받기위해 인덱스 삭제 후 데이터 추가 삽입

1
2
3
SQL> drop index sort2_ix02;
 
Index dropped.

 

 

sort2 테이블에 660개 row 추가입력

1
2
3
4
5
6
7
8
9
10
11
12
SQL>
DECLARE
    i NUMBER;
BEGIN
    FOR i IN 1982..(1981+660) LOOP
        INSERT INTO sort2 (col1) VALUES (i);
    END LOOP;
    COMMIT;
END;
/
 
PL/SQL procedure successfully completed.

 

 

sort2 테이블 블록별 row 갯수 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SQL>
set lines 200 pages 1000
select
dbms_rowid.rowid_block_number(rowid) blockno,
count(rowid)
from sort2
group by dbms_rowid.rowid_block_number(rowid)
order by 1;
 
   BLOCKNO COUNT(ROWID)
---------- ------------
       139            1
       140          660
       141          660
       142          660
       143          660

143번 블록이 다 차고 139번 블록에 새 값이 들어옴

 

 

sort2 테이블의 각 row별 file_id, block_id, rowid 확인(rowid 순으로 정렬해서 확인)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
SQL> 
set lines 200 pages 1000
select
dbms_rowid.rowid_relative_fno(rowid) rel_fno,
dbms_rowid.rowid_block_number(rowid) blockno,
rowid, 
col1
from sort2
order by rowid;
 
   REL_FNO    BLOCKNO ROWID                    COL1
---------- ---------- ------------------ ----------
         7        139 AAAGPRAAHAAAACLAAA       2641
         7        140 AAAGPRAAHAAAACMAAA          1
         7        140 AAAGPRAAHAAAACMAAB          2
         7        140 AAAGPRAAHAAAACMAAC          3
         7        140 AAAGPRAAHAAAACMAAD          4
.
.
         7        143 AAAGPRAAHAAAACPAKQ       2637
         7        143 AAAGPRAAHAAAACPAKR       2638
         7        143 AAAGPRAAHAAAACPAKS       2639
         7        143 AAAGPRAAHAAAACPAKT       2640
 
2641 rows selected.

rowid 순으로 정렬해서 보면 col1 컬럼이 순서대로 정렬되어있지 않음
col1이 1인 값이 들어있는 140블록보다 앞 블록인 139 블록에 col1이 2641인 값이 들어옴
(col1 컬럼값순으로 데이터 정렬이 되어있지 않은 상태)

 

 

이 상태에서 sort2 테이블에 인덱스 생성 시도(nosort)

1
2
3
4
5
SQL> create index sort2_ix02 on sort2(col1) nosort;
create index sort2_ix02 on sort2(col1) nosort
                           *
ERROR at line 1:
ORA-01409: NOSORT option may not be used; rows are not in ascending order

에러가 발생함

 

 

이렇게 rowid 순으로 정렬했을때 인덱스를 만드려는 컬럼의 데이터도 정렬이 되어있어야
nosort 옵션을 이용해서 인덱스를 생성할 수 있음
이 테스트에선 데이터 량이 많지 않아서 속도 비교가 의미가 없었음

 

 

테스트2. ctas 구문으로 생성된 데이터
이번엔 dba_objects에서 데이터를 가져와 sample 테이블을 만들고
이 테이블을 ctas를 이용해 정렬하면서 대량 데이터를 인덱스 생성용 테이블에 삽입한뒤 nosort 옵션으로 인덱스를 생성해봄

 

 

샘플 테이블 생성

1
2
3
4
SQL>
drop table sample purge;
create table sample tablespace noso as 
select * from dba_objects;

 

 

샘플 데이터 삽입

1
2
3
4
5
SQL>
insert /*+ append parallel */ into sample select /*+ parallel */ * from sample;
commit;
(반복)
369648 rows created.

 

 

sort3 테이블 생성(object_id 순으로 정렬)

1
2
3
SQL> 
drop table sort3 purge;
create table sort3 tablespace noso as select * from sample order by object_id;

 

 

trace 실행 후 인덱스 생성

1
2
3
4
5
6
7
8
9
10
11
SQL> alter session set events '10046 trace name context forever, level 12';
 
Session altered.
 
SQL> create index sort3_ix01 on sort3(object_id);
 
Index created.
 
SQL> alter session set events '10046 trace name context off';
 
Session altered.

 

 

생성된 trace 확인

1
2
3
4
5
6
7
8
9
10
SQL>
set lines 200 pages 1000
col name for a20
col value for a80
select name, value from v$diag_info
where name = 'Default Trace File';
 
NAME                 VALUE
-------------------- --------------------------------------------------------------------------------
Default Trace File   /ORA19/app/oracle/diag/rdbms/oracle19/oracle19/trace/oracle19_ora_4182.trc

 

 

tkprof 실행

1
2
3
4
5
$ tkprof /ORA19/app/oracle/diag/rdbms/oracle19/oracle19/trace/oracle19_ora_4182.trc sort3_01.txt sys=no
 
TKPROF: Release 19.0.0.0.0 - Development on Mon Jan 29 13:02:42 2024
 
Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

 

 

트레이스 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$ vi sort3_01.txt
SQL ID: bx0wu5kbucyfn Plan Hash: 1700858464
 
create index sort3_ix01 on sort3(object_id)
 
 
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          1          0           0
Execute      1      0.32       0.39      12299      12371       2550           0
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.32       0.39      12299      12372       2550           0
 
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 81
Number of plan statistics captured: 1
 
Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         1          1          1  INDEX BUILD NON UNIQUE SORT3_IX01 (cr=12377 pr=12299 pw=1608 time=391418 us starts=1)(object id 0)
    739296     739296     739296   SORT CREATE INDEX (cr=12302 pr=12299 pw=0 time=187492 us starts=1)
    739296     739296     739296    TABLE ACCESS FULL SORT3 (cr=12302 pr=12299 pw=0 time=41399 us starts=1 cost=3391 size=3696480 card=739296)
 
 
Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  PGA memory operation                          182        0.00          0.00
  index (re)build lock or pin object              4        0.00          0.00
  asynch descriptor resize                        1        0.00          0.00
  Disk file operations I/O                        2        0.00          0.00
  direct path read                              202        0.00          0.01
  direct path write                             416        0.00          0.09
  log file sync                                   1        0.00          0.00
  SQL*Net message to client                       1        0.00          0.00
  SQL*Net message from client                     1        0.00          0.00
********************************************************************************

인덱스 생성 중 sort를 한것이 확인됨(Row Source Operation 의 SORT CREATE INDEX 부분)
인덱스 생성시 시간이 391418 us 소요됨

 

 

sqlplus 세션 재접속 후 진행

 

 

테스트를 위해 기존 인덱스 삭제

1
2
3
SQL> drop index sort3_ix01;
 
Index dropped.

 

 

trace 실행 후 인덱스 생성(nosort)

1
2
3
4
5
6
7
8
9
10
11
SQL> alter session set events '10046 trace name context forever, level 12';
 
Session altered.
 
SQL> create index sort3_ix02 on sort3(object_id) nosort;
 
Index created.
 
SQL> alter session set events '10046 trace name context off';
 
Session altered.

 

 

생성된 trace 확인

1
2
3
4
5
6
7
8
9
10
SQL>
set lines 200 pages 1000
col name for a20
col value for a80
select name, value from v$diag_info
where name = 'Default Trace File';
 
NAME                 VALUE
-------------------- --------------------------------------------------------------------------------
Default Trace File   /ORA19/app/oracle/diag/rdbms/oracle19/oracle19/trace/oracle19_ora_4313.trc

 

 

tkprof 실행

1
2
3
4
5
$ tkprof /ORA19/app/oracle/diag/rdbms/oracle19/oracle19/trace/oracle19_ora_4313.trc sort3_02.txt sys=no
 
TKPROF: Release 19.0.0.0.0 - Development on Mon Jan 29 13:07:04 2024
 
Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

 

 

트레이스 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
$ vi sort3_01.txt
SQL ID: 7vuk0vrjhvn36 Plan Hash: 4070344199
 
create index sort3_ix02 on sort3(object_id) nosort
 
 
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          5          7           0
Execute      1      0.22       0.31      12300      12367       2545           0
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.22       0.32      12300      12372       2552           0
 
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 81
Number of plan statistics captured: 1
 
Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         1          1          1  INDEX BUILD NON UNIQUE SORT3_IX02 (cr=12377 pr=12300 pw=1608 time=318877 us starts=1)(object id 0)
    739296     739296     739296   TABLE ACCESS FULL SORT3 (cr=12302 pr=12299 pw=0 time=102187 us starts=1 cost=3391 size=3696480 card=739296)
 
 
Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  PGA memory operation                           19        0.00          0.00
  index (re)build lock or pin object              4        0.00          0.00
  reliable message                                1        0.00          0.00
  enq: KO - fast object checkpoint                1        0.01          0.01
  asynch descriptor resize                        1        0.00          0.00
  Disk file operations I/O                        2        0.00          0.00
  direct path read                              202        0.00          0.01
  direct path write                             416        0.00          0.09
  db file sequential read                         1        0.00          0.00
  log file sync                                   1        0.00          0.00
  SQL*Net message to client                       1        0.00          0.00
  SQL*Net message from client                     1        0.00          0.00
********************************************************************************

기존 인덱스 생성 트레이스에 있던 SORT CREATE INDEX 부분이 없음
인덱스 생성시 시간이 318877 us 소요됨

(nosort 옵션 미사용 인덱스 생성시 시간이 391418 us 소요됨)

 

 

참고로 더 많은데이터를 넣어 테스트해보려고 했지만
테스트1 처럼 블록할당을 랜덤하게 받아서 데이터가 섞이는 현상이 발생해 이정도 데이터로만 테스트하였음

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
시도한 테스트1. connect by
drop table sort4 purge;
create table sort4 (col1 number) tablespace noso;
insert into sort4(col1)
select level
from dual
connect by level <= 100000
order by level asc;
commit;
set lines 200 pages 1000
select
dbms_rowid.rowid_block_number(rowid) blockno,
rowid, col1
from sort4
order by 1;
결과 : 정렬 안되서 들어가서 nosort 옵션 인덱스 생성 안됨
 
시도한 테스트2. ctas 대량(테스트2와 같이 할때 더 많이 insert)
drop table sample purge;
create table sample tablespace noso as 
select * from dba_objects;
insert /*+ append parallel */ into sample select /*+ parallel */ * from sample;
commit;
(insert 반복 더 많이)
drop table sort5 purge;
create table sort5 tablespace noso as select * from sample order by object_id;
set lines 200 pages 1000
select
dbms_rowid.rowid_block_number(rowid) blockno,
rowid, col1
from sort5
order by 1;
결과 : 정렬 안되서 들어가서 nosort 옵션 인덱스 생성 안됨

 

 

결론 :

적은 데이터로 테스트 했을때는 nosort 옵션 미사용시 391418 us(0.39초) 가 소요되었고, nososrt 옵션 사용시 318877 us(0.31초) 가 소요됨(0.08초 빠름)

하지만 현재 테스트환경이 assm 방식을 사용중이기 때문에 익스텐트 내 블록의 할당 순서가 순차적이지 않을 수 있어(세션의 pid에 따라 블록 할당 순서가 결정됨) 대량 데이터를 order by 와 함께 insert 한다고 해도 nosort 옵션을 사용하지 못할 확률이 높음
이렇게 제약조건이 많아서 실제 업무에선 사용하기 어려울것으로 보임

 

 

mssm 방식으로 테스트했을때는 order by 를 사용해 insert 시 블록을 순차적으로 할당받아 데이터가 정상적으로 들어갔음
만약 의도적으로 mssm을 사용하는 곳이 있다면 이 방법을 통해 인덱스 생성시 시간을 절약할 수 있음
오라클 19c 인덱스 생성시 nosort 옵션(mssm 환경) ( https://positivemh.tistory.com/1016 )

 

 

참조 : 

https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/CREATE-INDEX.html#GUID-1F89BBC0-825F-4215-AF71-7588E31D8BFE__I2129491
https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/logical-storage-structures.html#GUID-52FE1A8C-74EA-4B81-B1AC-69FD34252659
https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/managing-tablespaces.html#GUID-5254F3ED-DDFA-4797-B09C-A49DC62E80B0
https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/logical-storage-structures.html#GUID-684E6324-A874-4304-8015-5634199BEE81
https://docs.oracle.com/en/database/oracle/oracle-database/19/cncpt/logical-storage-structures.html#GUID-4AF2D61A-8675-4D48-97A4-B20F401ADA16
https://www.dba-oracle.com/t_create_index_nosort.htm
https://docs.oracle.com/en/error-help/db/ora-01409/
https://www.orafaq.com/wiki/Data_block_address
https://jonathanlewis.wordpress.com/2012/11/27/iot-load/
TRANSACTION INTERNALS IN ORACLE 10GR2 서적 182p