프린트 하기

OS환경 : Oracle Linux 7.6 (64bit)

 

DB 환경 : Oracle Database 19.11.0.0

 

방법 : 오라클 19c itas 시 full scan과 index scan 속도 비교 테스트

19c 환경에서 샘플 테이블 생성후 

itas(insert into select * from table) 로 데이터 삽입시 

full scan으로 읽어서 넣는게 빠른지, index scan으로 읽어서 넣는게 빠른지 테스트해봄

1. OPTIMIZER STATISTICS GATHERING 기능을 ON(default) 상태로 테스트

2. OPTIMIZER STATISTICS GATHERING 기능을 OFF 상태로 테스트

3. OPTIMIZER STATISTICS GATHERING 기능을 OFF + PARALLEL 테스트

 

 

샘플 테이블 생성

1
2
3
4
5
6
7
8
9
SQL>
drop table sample_t purge;
create table sample_t 
(id1 number, id2 number, name varchar2(10),  
date1 varchar2(8), date2 varchar2(8), date3 date, 
phone varchar2(13), price number, qty number, 
test1 number,  test2 varchar2(5), test3 varchar2(4)
)
nologging;

 

 

샘플 테이블 데이터 삽입

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>
DECLARE
TYPE tbl_ins IS TABLE OF sample_t%ROWTYPE INDEX BY BINARY_INTEGER;
w_ins tbl_ins;
BEGIN
FOR d IN 1..10 LOOP
FOR i IN 1..1000000 LOOP 
   w_ins(i).id1   := i;
   w_ins(i).id2   := i||ceil(dbms_random.value(110000000));
   w_ins(i).name  := dbms_random.string('x',5);
   w_ins(i).date1 := round(dbms_random.value(2010,2021))||to_char(round(dbms_random.value(1,12)), 'FM09')||to_char( round(dbms_random.value(1,28)), 'FM09');
   w_ins(i).date2 := '2021'||to_char(round(dbms_random.value(1,12)) , 'FM09')||to_char(round(dbms_random.value(1,28)), 'FM09');
   w_ins(i).date3 := to_date(round(dbms_random.value(2010,2021))||'-'||round(dbms_random.value(1,12))||'-'||round(dbms_random.value(1,28))||' '||round(dbms_random.value(123))||':'||round(dbms_random.value(059))||':'||round(dbms_random.value(059)), 'YYYY-MM-DD HH24:MI:SS');
   w_ins(i).phone := '010-'||ceil(dbms_random.value(10009999))||'-'||ceil(dbms_random.value(10009999));
   w_ins(i).price := ceil(dbms_random.value(110))*1000;
   w_ins(i).qty   := ceil(dbms_random.value(110));
   w_ins(i).test1 := 1234;
   w_ins(i).test2 := 'SQLP';
   w_ins(i).test3 := 'A'||ceil(dbms_random.value(100999));
END LOOP;
FORALL i in 1..1000000 INSERT INTO sample_t VALUES w_ins(i);
   COMMIT;
END LOOP;
END;
/

 

 

샘플 테이블 인덱스 생성

1
2
3
SQL> create index ix_sam1 on sample_t(id1); 
 
Index created.

 

 

통계정보 생성

1
2
3
SQL> exec dbms_stats.gather_table_stats('IMSI''SAMPLE_T'cascade=>TRUE);
 
PL/SQL procedure successfully completed.

 

 

샘플테이블 건수 확인

1
2
3
4
5
SQL> select count(*from sample_t;
 
  COUNT(*)
----------
  10000000

1천만건이 삽입됨

 

 

샘플 테이블 용량 조회

1
2
3
4
5
6
7
8
SQL> 
select segment_name, bytes/1024/1024 mb 
from dba_segments 
where segment_name = 'SAMPLE_T';
 
SEGMENT_NAME         MB
------------- ----------
SAMPLE_T                927

약 920MB임

 

 

1. OPTIMIZER STATISTICS GATHERING 기능을 ON(default) 상태로 테스트

테스트1. 전체 데이터로 테이블 생성(FULL SCAN)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SQL> 
drop table itable_1 purge;
create table itable_1 as select * from sample_t where 1=0;
 
SQL> 
insert /*+ gather_plan_statistics append */ into itable_1 
select /*+ full(st) */ * from sample_t st where id1 >= 1;
 
10000000 rows created.
 
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULLNULL'ADVANCED ALLSTATS LAST');
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation             | Name     | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers | Reads  | Writes |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT         |        |       1 |          |       | 32351 (100)|          |      0 |00:00:07.91 |      308K|    117K|    117K|    |    |       |
|   1 |  LOAD AS SELECT          | ITABLE_1 |       1 |          |       |        |          |      0 |00:00:07.91 |      308K|    117K|    117K|  2070K|  2070K| 2070K (0)|
|   2 |   OPTIMIZER STATISTICS GATHERING |        |       1 |       10M|   762M| 32351    (2)| 00:00:02 |     10M|00:00:06.55 |      184K|    117K|      0 |   256K|   256K|       |
|*  3 |    TABLE ACCESS FULL         | SAMPLE_T |       1 |       10M|   762M| 32351    (2)| 00:00:02 |     10M|00:00:02.00 |      184K|    117K|      0 |    |    |       |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

전체 데이터 삽입 시 full scan을 이용했을 때 cost가 32351이 나오고 시간이 7초 소요됨

 

 

테스트2. 전체 데이터로 테이블 생성(INDEX SCAN)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SQL> 
drop table itable_2 purge;
create table itable_2 as select * from sample_t where 1=0;
 
SQL> 
insert /*+ gather_plan_statistics append */ into itable_2 
select /*+ index(st ix_sam1) */ * from sample_t st where id1 >= 1;
 
10000000 rows created.
 
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULLNULL'ADVANCED ALLSTATS LAST');
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                  | Name     | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |    A-Time     | Buffers | Reads  | Writes |    OMem |    1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT              |      |    1 |       |       |    10M(100)|       |      0 |00:00:14.74 |    9863K|    139K|     117K|         |         |        |
|   1 |  LOAD AS SELECT               | ITABLE_2 |    1 |       |       |        |       |      0 |00:00:14.74 |    9863K|    139K|     117K|    2070K|    2070K| 2070K (0)|
|   2 |   OPTIMIZER STATISTICS GATHERING      |      |    1 |    10M|   762M|    10M  (1)| 00:06:32 |     10M|00:00:12.67 |    9738K|    139K|       0 |     256K|     256K|        |
|   3 |    TABLE ACCESS BY INDEX ROWID BATCHED| SAMPLE_T |    1 |    10M|   762M|    10M  (1)| 00:06:32 |     10M|00:00:06.99 |    9738K|    139K|       0 |         |         |        |
|*  4 |     INDEX RANGE SCAN              | IX_SAM1  |    1 |    10M|       | 22153   (1)| 00:00:01 |     10M|00:00:01.21 |   22287 |  22286 |       0 |         |         |        |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

전체 데이터 삽입 시 index scan을 이용했을 때 cost가 10M이 나오고 시간이 14초 소요됨

 

 

테스트3. 일부 데이터로 테이블 생성(FULL SCAN)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SQL> 
drop table itable_3 purge;
create table itable_3 as select * from sample_t where 1=0;
 
SQL> 
insert /*+ gather_plan_statistics append */ into itable_3
select /*+ full(st) */ * from sample_t st where id1 <= 10000;
 
100000 rows created.
 
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULLNULL'ADVANCED ALLSTATS LAST');
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation             | Name     | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers | Reads  | Writes |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT         |        |       1 |          |       | 32208 (100)|          |      0 |00:00:00.89 |      119K|    117K|   1149 |    |    |       |
|   1 |  LOAD AS SELECT          | ITABLE_3 |       1 |          |       |        |          |      0 |00:00:00.89 |      119K|    117K|   1149 |  2070K|  2070K| 2070K (0)|
|   2 |   OPTIMIZER STATISTICS GATHERING |        |       1 |      100K|  7812K| 32208    (1)| 00:00:02 |    100K|00:00:03.30 |      117K|    117K|      0 |   256K|   256K|       |
|*  3 |    TABLE ACCESS FULL         | SAMPLE_T |       1 |      100K|  7812K| 32208    (1)| 00:00:02 |    100K|00:00:03.21 |      117K|    117K|      0 |    |    |       |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

일부 데이터 삽입 시 full scan을 이용했을 때 cost가 32208이 나오고 시간이 0초 89 소요됨

 

 

테스트4. 일부 데이터로 테이블 생성(INDEX SCAN)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SQL> 
drop table itable_4 purge;
create table itable_4 as select * from sample_t where 1=0;
 
SQL> 
insert /*+ gather_plan_statistics append */ into itable_4
select /*+ index(st ix_sam1) */ * from sample_t st where id1 <= 10000;
 
100000 rows created.
 
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULLNULL'ADVANCED ALLSTATS LAST');
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                  | Name     | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |    A-Time     | Buffers | Reads  | Writes |    OMem |    1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT              |      |    1 |       |       |   100K(100)|       |      0 |00:00:00.17 |     100K|    744 |    1148 |         |         |        |
|   1 |  LOAD AS SELECT               | ITABLE_4 |    1 |       |       |        |       |      0 |00:00:00.17 |     100K|    744 |    1148 |    2070K|    2070K| 2070K (0)|
|   2 |   OPTIMIZER STATISTICS GATHERING      |      |    1 |    100K|  7812K|   100K  (1)| 00:00:04 |    100K|00:00:00.14 |   98820 |    744 |       0 |     256K|     256K|        |
|   3 |    TABLE ACCESS BY INDEX ROWID BATCHED| SAMPLE_T |    1 |    100K|  7812K|   100K  (1)| 00:00:04 |    100K|00:00:00.06 |   98612 |    744 |       0 |         |         |        |
|*  4 |     INDEX RANGE SCAN              | IX_SAM1  |    1 |    100K|       |   224   (1)| 00:00:01 |    100K|00:00:00.02 |     211 |    209 |       0 |         |         |        |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

일부 데이터 삽입 시 index scan을 이용했을 때 cost가 100K가 나오고 시간이 0초 17 소요됨

 

 

4개 테스트 모두 실행계획에서 공통적으로 OPTIMIZER STATISTICS GATHERING 라는 실행계획이 나옴

이는 벌크 인서트(append등) 시 통계정보를 생성해주는 오라클의 기능인데 이 기능때문에 속도가 조금 더 느려짐

1
2
3
4
5
6
7
SQL> select table_name, last_analyzed from dba_tables where table_name like 'ITABLE_%';
TABLE_NAME     LAST_ANALYZE
-----------  ------------
ITABLE_1     13-APR-22
ITABLE_2     13-APR-22
ITABLE_3     13-APR-22
ITABLE_4     13-APR-22

 

 

OPTIMIZER STATISTICS GATHERING이 활성화 된 상태에서 결론

전체 데이터 삽입

속도 : FULLSCAN : 7초, INDEXSCAN : 14초

COST : FULLSCAN : 32351, INDEXSCAN : 10M

일부 데이터 삽입

속도 : FULLSCAN : 0초 89, INDEXSCAN : 0초 17

COST : FULLSCAN : 32208, INDEXSCAN : 100K

 

 

전체 데이터 삽입시에는 FULLSCAN으로 삽입하는게 낫고

일부 데이터 삽입시에는 INDEXSCAN으로 삽입하는게 근소하게 빠름

(데이터 읽는량(인덱스 손익분기점)에 따라 차이가 날듯함)

COST는 오히려 INDEXSCAN시가 더 높게 나옴

 

 

2. OPTIMIZER STATISTICS GATHERING 기능을 OFF 상태로 테스트

OPTIMIZER STATISTICS GATHERING 기능을 OFF 한뒤 다시 테스트

1
2
3
4
5
파라미터 변경
SQL> alter session set "_optimizer_gather_stats_on_load" = false;
또는
SQL 마다 힌트 삽입
SQL> select /*+ no_gather_optimizer_statistics */ from table;

 

 

테스트1. 전체 데이터로 테이블 생성(FULL SCAN)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SQL> 
drop table itable_1 purge;
create table itable_1 as select * from sample_t where 1=0;
 
SQL> 
insert /*+ gather_plan_statistics append */ into itable_1 
select /*+ full(st) */ * from sample_t st where id1 >= 1;
 
10000000 rows created.
 
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULLNULL'ADVANCED ALLSTATS LAST');
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation       | Name     | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time    | A-Rows |   A-Time   | Buffers | Reads  | Writes |  OMem |  1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT   |          |      1 |    |    | 32351 (100)|        |      0 |00:00:03.96 |     241K|    117K|    117K|      |      |         |
|   1 |  LOAD AS SELECT    | ITABLE_1 |      1 |    |    |         |        |      0 |00:00:03.96 |     241K|    117K|    117K|  2070K|  2070K| 2070K (0)|
|*  2 |   TABLE ACCESS FULL| SAMPLE_T |      1 |     10M|   762M| 32351   (2)| 00:00:02 |     10M|00:00:01.98 |     117K|    117K|    0 |      |      |         |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------

전체 데이터 삽입 시 full scan을 이용했을 때 cost가 32351이 나오고 시간이 3초 소요됨

 

 

테스트2. 전체 데이터로 테이블 생성(INDEX SCAN)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SQL> 
drop table itable_2 purge;
create table itable_2 as select * from sample_t where 1=0;
 
SQL> 
insert /*+ gather_plan_statistics append */ into itable_2 
select /*+ index(st ix_sam1) */ * from sample_t st where id1 >= 1;
 
10000000 rows created.
 
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULLNULL'ADVANCED ALLSTATS LAST');
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                 | Name    | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time    | Buffers | Reads  | Writes |  OMem |  1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT             |        |      1 |      |      |    10M(100)|      |     0 |00:00:08.00 |    9797K|    138K|    117K|        |        |           |
|   1 |  LOAD AS SELECT              | ITABLE_2 |      1 |      |      |           |      |     0 |00:00:08.00 |    9797K|    138K|    117K|  2070K|  2070K| 2070K (0)|
|   2 |   TABLE ACCESS BY INDEX ROWID BATCHED| SAMPLE_T |      1 |     10M|   762M|    10M  (1)| 00:06:32 |    10M|00:00:05.69 |    9673K|    138K|      0 |        |        |           |
|*  3 |    INDEX RANGE SCAN             | IX_SAM1    |      1 |     10M|      | 22153   (1)| 00:00:01 |    10M|00:00:01.10 |   22287 |  22076 |      0 |        |        |           |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

전체 데이터 삽입 시 index scan을 이용했을 때 cost가 10M이 나오고 시간이 8초 소요됨

 

 

테스트3. 일부 데이터로 테이블 생성(FULL SCAN)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SQL> 
drop table itable_3 purge;
create table itable_3 as select * from sample_t where 1=0;
 
SQL> 
insert /*+ gather_plan_statistics append */ into itable_3
select /*+ full(st) */ * from sample_t st where id1 <= 10000;
 
100000 rows created.
 
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULLNULL'ADVANCED ALLSTATS LAST');
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation       | Name     | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time    | A-Rows |   A-Time   | Buffers | Reads  | Writes |  OMem |  1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT   |          |      1 |    |    | 32208 (100)|        |      0 |00:00:00.25 |     119K|    117K|   1149 |      |      |         |
|   1 |  LOAD AS SELECT    | ITABLE_3 |      1 |    |    |         |        |      0 |00:00:00.25 |     119K|    117K|   1149 |  2070K|  2070K| 2070K (0)|
|*  2 |   TABLE ACCESS FULL| SAMPLE_T |      1 |    100K|  7812K| 32208   (1)| 00:00:02 |    100K|00:00:02.42 |     117K|    117K|    0 |      |      |         |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------

일부 데이터 삽입 시 full scan을 이용했을 때 cost가 32208이 나오고 시간이 0초 25 소요됨

 

 

테스트4. 일부 데이터로 테이블 생성(INDEX SCAN)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SQL> 
drop table itable_4 purge;
create table itable_4 as select * from sample_t where 1=0;
 
SQL> 
insert /*+ gather_plan_statistics append */ into itable_4
select /*+ index(st ix_sam1) */ * from sample_t st where id1 <= 10000;
 
100000 rows created.
 
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULLNULL'ADVANCED ALLSTATS LAST');
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                 | Name    | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time    | Buffers | Writes |  OMem |  1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT             |        |      1 |      |      |   100K(100)|      |     0 |00:00:00.09 |     102K|   1148 |       |       |          |
|   1 |  LOAD AS SELECT              | ITABLE_4 |      1 |      |      |           |      |     0 |00:00:00.09 |     102K|   1148 |  2070K|  2070K| 2070K (0)|
|   2 |   TABLE ACCESS BY INDEX ROWID BATCHED| SAMPLE_T |      1 |    100K|  7812K|   100K  (1)| 00:00:04 |    100K|00:00:00.06 |     100K|     0 |       |       |          |
|*  3 |    INDEX RANGE SCAN             | IX_SAM1    |      1 |    100K|      |   224   (1)| 00:00:01 |    100K|00:00:00.01 |     211 |     0 |       |       |          |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

일부 데이터 삽입 시 index scan을 이용했을 때 cost가 100K가 나오고 시간이 0초 09 소요됨

 

 

OPTIMIZER STATISTICS GATHERING이 비활성화 된 상태에서 결론

전체 데이터 삽입

속도 : FULLSCAN : 3초, INDEXSCAN : 8초

COST : FULLSCAN : 32351, INDEXSCAN : 10M

일부 데이터 삽입

속도 : FULLSCAN : 0초 25, INDEXSCAN : 0초 09

COST : FULLSCAN : 32208, INDEXSCAN : 100K

 

 

OPTIMIZER STATISTICS GATHERING이 비활성화 된 상태에서는

전체적으로 활성화 된 상태보다 속도가 빠르게 실행되었고

전체 데이터 삽입시에는 FULLSCAN으로 삽입하는게 낫고

일부 데이터 삽입시에는 INDEXSCAN으로 삽입하는게 근소하게 빠름

(데이터 읽는량(인덱스 손익분기점)에 따라 차이가 날듯함)

COST는 오히려 INDEXSCAN시가 더 높게 나옴

 

 

3. OPTIMIZER STATISTICS GATHERING 기능을 OFF + PARALLEL 테스트

parallel dml enable 

1
2
3
SQL> alter session enable parallel dml;
 
Session altered.

 

 

테스트1. parallel 전체 데이터로 테이블 생성(FULL SCAN)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
SQL> 
drop table itable_1 purge;
create table itable_1 as select * from sample_t where 1=0;
 
SQL> 
insert /*+ gather_plan_statistics append parallel(i1 4) */ into itable_1 i1
select /*+ full(st) parallel(st 4) */ * from sample_t st where id1 >= 1;
 
10000000 rows created.
 
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULLNULL'ADVANCED ALLSTATS LAST');
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation               | Name     | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time    |    TQ  |IN-OUT| PQ Distrib | A-Rows |   A-Time   | Buffers |    OMem |    1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT           |          |      1 |    |    |  8971 (100)|        |     |    |         |        8 |00:00:02.62 |  28 |         |         |        |
|   1 |  PX COORDINATOR            |          |      1 |    |    |         |        |     |    |         |        8 |00:00:02.62 |  28 | 73728 | 73728 |        |
|   2 |   PX SEND QC (RANDOM)           | :TQ10000 |      0 |     10M|   762M|  8971   (1)| 00:00:01 |  Q1,00 | P->| QC (RAND)  |        0 |00:00:00.01 |   0 |         |         |        |
|   3 |    LOAD AS SELECT (HYBRID TSM/HWMB)| ITABLE_1 |      0 |    |    |         |        |  Q1,00 | PCWP |         |        0 |00:00:00.01 |   0 |      15M|      15M| 2070K (0)|
|   4 |     PX BLOCK ITERATOR           |          |      0 |     10M|   762M|  8971   (1)| 00:00:01 |  Q1,00 | PCWC |         |        0 |00:00:00.01 |   0 |         |         |        |
|*  5 |      TABLE ACCESS FULL           | SAMPLE_T |      0 |     10M|   762M|  8971   (1)| 00:00:01 |  Q1,00 | PCWP |         |        0 |00:00:00.01 |   0 |         |         |        |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

전체 데이터 삽입 시 parallel full scan을 이용했을 때 cost가 8971이 나오고 시간이 2초 소요됨

 

 

테스트2. parallel 전체 데이터로 테이블 생성(INDEX SCAN)

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> 
drop table itable_2 purge;
create table itable_2 as select * from sample_t where 1=0;
 
SQL> 
insert /*+ gather_plan_statistics append parallel(i2 4) */ into itable_2 i2
select /*+ index(st ix_sam1) parallel(st 4) */ * from sample_t st where id1 >= 1;
 
10000000 rows created.
 
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULLNULL'ADVANCED ALLSTATS LAST');
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                  | Name     | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |    TQ    |IN-OUT| PQ Distrib | A-Rows |     A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT              |         |        1 |        |       |    10M(100)|           |    |      |        |       8 |00:00:07.86 |      9 |        |        |           |
|   1 |  PX COORDINATOR               |         |        1 |        |       |        |           |    |      |        |       8 |00:00:07.86 |      9 | 73728 | 73728 |           |
|   2 |   PX SEND QC (RANDOM)              | :TQ10001 |        0 |     10M|   762M|    10M  (1)| 00:06:32 |  Q1,01 | P->| QC (RAND)  |       0 |00:00:00.01 |      0 |        |        |           |
|   3 |    LOAD AS SELECT (HYBRID TSM/HWMB)      | ITABLE_2 |        0 |        |       |        |           |  Q1,01 | PCWP |        |       0 |00:00:00.01 |      0 |     16M|     16M| 2070K (0)|
|   4 |     PX RECEIVE                  |         |        0 |     10M|   762M|    10M  (1)| 00:06:32 |  Q1,01 | PCWP |        |       0 |00:00:00.01 |      0 |        |        |           |
|   5 |      PX SEND ROUND-ROBIN          | :TQ10000 |        0 |     10M|   762M|    10M  (1)| 00:06:32 |  Q1,00 | S->| RND-ROBIN  |       0 |00:00:00.01 |      0 |        |        |           |
|   6 |       PX SELECTOR              |         |        0 |        |       |        |           |  Q1,00 | SCWC |        |       0 |00:00:00.01 |      0 |        |        |           |
|   7 |        TABLE ACCESS BY INDEX ROWID BATCHED| SAMPLE_T |        0 |     10M|   762M|    10M  (1)| 00:06:32 |  Q1,00 | SCWC |        |       0 |00:00:00.01 |      0 |        |        |           |
|*  8 |     INDEX RANGE SCAN          | IX_SAM1  |        0 |     10M|       | 22153     (1)| 00:00:01 |  Q1,00 | SCWP |        |       0 |00:00:00.01 |      0 |        |        |           |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

전체 데이터 삽입 시 parallel index scan을 이용했을 때 cost가 10M이 나오고 시간이 7초 소요됨

 

 

테스트3. parallel 일부 데이터로 테이블 생성(FULL SCAN)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
SQL> 
drop table itable_3 purge;
create table itable_3 as select * from sample_t where 1=0;
 
SQL> 
insert /*+ gather_plan_statistics append parallel(i3 4) */ into itable_3 i3
select /*+ full(st) parallel(st 4) */ * from sample_t st where id1 <= 10000;
 
100000 rows created.
 
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULLNULL'ADVANCED ALLSTATS LAST');
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation               | Name     | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time    |    TQ  |IN-OUT| PQ Distrib | A-Rows |   A-Time   | Buffers |    OMem |    1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT           |          |      1 |    |    |  8931 (100)|        |     |    |         |        8 |00:00:00.09 |      29 |         |         |        |
|   1 |  PX COORDINATOR            |          |      1 |    |    |         |        |     |    |         |        8 |00:00:00.09 |      29 | 73728 | 73728 |        |
|   2 |   PX SEND QC (RANDOM)           | :TQ10000 |      0 |    100K|  7812K|  8931   (1)| 00:00:01 |  Q1,00 | P->| QC (RAND)  |        0 |00:00:00.01 |       0 |         |         |        |
|   3 |    LOAD AS SELECT (HYBRID TSM/HWMB)| ITABLE_3 |      0 |    |    |         |        |  Q1,00 | PCWP |         |        0 |00:00:00.01 |       0 |    3260K|    3260K| 2070K (0)|
|   4 |     PX BLOCK ITERATOR           |          |      0 |    100K|  7812K|  8931   (1)| 00:00:01 |  Q1,00 | PCWC |         |        0 |00:00:00.01 |       0 |         |         |        |
|*  5 |      TABLE ACCESS FULL           | SAMPLE_T |      0 |    100K|  7812K|  8931   (1)| 00:00:01 |  Q1,00 | PCWP |         |        0 |00:00:00.01 |       0 |         |         |        |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

일부 데이터 삽입 시 full scan을 이용했을 때 cost가 8931이 나오고 시간이 0초 09 소요됨

 

 

테스트4. parallel 일부 데이터로 테이블 생성(INDEX SCAN)

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> 
drop table itable_4 purge;
create table itable_4 as select * from sample_t where 1=0;
 
SQL> 
insert /*+ gather_plan_statistics append parallel(i4 4) */ into itable_4 i4
select /*+ index(st ix_sam1) parallel(st 4) */ * from sample_t st where id1 <= 10000;
 
100000 rows created.
 
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULLNULL'ADVANCED ALLSTATS LAST');
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                  | Name     | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |    TQ    |IN-OUT| PQ Distrib | A-Rows |     A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT              |         |        1 |        |       |   100K(100)|           |    |      |        |       8 |00:00:00.11 |      9 |        |        |           |
|   1 |  PX COORDINATOR               |         |        1 |        |       |        |           |    |      |        |       8 |00:00:00.11 |      9 | 73728 | 73728 |           |
|   2 |   PX SEND QC (RANDOM)              | :TQ10001 |        0 |    100K|  7812K|   100K  (1)| 00:00:04 |  Q1,01 | P->| QC (RAND)  |       0 |00:00:00.01 |      0 |        |        |           |
|   3 |    LOAD AS SELECT (HYBRID TSM/HWMB)      | ITABLE_4 |        0 |        |       |        |           |  Q1,01 | PCWP |        |       0 |00:00:00.01 |      0 |  3701K|  3701K| 2070K (0)|
|   4 |     PX RECEIVE                  |         |        0 |    100K|  7812K|   100K  (1)| 00:00:04 |  Q1,01 | PCWP |        |       0 |00:00:00.01 |      0 |        |        |           |
|   5 |      PX SEND ROUND-ROBIN          | :TQ10000 |        0 |    100K|  7812K|   100K  (1)| 00:00:04 |  Q1,00 | S->| RND-ROBIN  |       0 |00:00:00.01 |      0 |        |        |           |
|   6 |       PX SELECTOR              |         |        0 |        |       |        |           |  Q1,00 | SCWC |        |       0 |00:00:00.01 |      0 |        |        |           |
|   7 |        TABLE ACCESS BY INDEX ROWID BATCHED| SAMPLE_T |        0 |    100K|  7812K|   100K  (1)| 00:00:04 |  Q1,00 | SCWC |        |       0 |00:00:00.01 |      0 |        |        |           |
|*  8 |     INDEX RANGE SCAN          | IX_SAM1  |        0 |    100K|       |   224     (1)| 00:00:01 |  Q1,00 | SCWP |        |       0 |00:00:00.01 |      0 |        |        |           |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

일부 데이터 삽입 시 index scan을 이용했을 때 cost가 100K가 나오고 시간이 0초 11 소요됨

 

 

OPTIMIZER STATISTICS GATHERING이 비활성화 된 상태 + parallel 병렬 처리 까지 했을 때 결론

전체 데이터 삽입

속도 : FULLSCAN : 2초, INDEXSCAN : 7초

COST : FULLSCAN : 9871, INDEXSCAN : 10M

일부 데이터 삽입

속도 : FULLSCAN : 0초 09, INDEXSCAN : 0초 11

COST : FULLSCAN : 8931, INDEXSCAN : 100K

 

 

OPTIMIZER STATISTICS GATHERING이 비활성화 된 상태에서는 parallel 까지 사용한 결과

전체적으로 parallel 을 사용하기 전보다 속도가 빠르게 실행되었고

전체 데이터 삽입시에는 FULLSCAN으로 삽입하는게 낫고

일부 데이터 삽입시에도 FULLSCAN으로 삽입하는게 근소하게 빠름

(데이터 읽는량(인덱스 손익분기점)에 따라 차이가 날듯함)

COST는 오히려 INDEXSCAN시가 더 높게 나옴

 

 

전체 비교

 

 

결론 :

ITAS 시 통계정보 수집하는 파라미터 on off 여부는 선택이지만 parallel 은 CPU만 여유롭다면 사용하는게 속도측면에서 이익이 있음

전체 데이터를 넣을 경우 FULLSCAN을 사용하는게 낫고 소량 데이터를 넣을 경우 INDEX를 이용하는게 나음

 

 

참조 : 

https://hrjeong.tistory.com/223

https://positivemh.tistory.com/808