Oracle/Tuning2018. 12. 8. 09:39

FK는 두 가지 원인으로 인해 DML 성능 저하가 발생한다. 첫 번째는 FK 인덱스 유지 비용이고, 두 번째 이유는 부모 테이블에 대한 룩업 작업이다. 이 중 후자가 성능 저하의 주요 원인이다.


테스트를 위해 아래와 같이 테이블을 생성하자. t1은 부모 테이블, t2는 테이블 인덱스와 FK가 없으며, t3는 인덱스, t4는 인덱스와 FK가 존재한다.

-- 1
DROP TABLE t1 CASCADE CONSTRAINT PURGE;
DROP TABLE t2 PURGE;
DROP TABLE t3 PURGE;
DROP TABLE t4 PURGE;

CREATE TABLE t1 AS SELECT ROWNUM AS c1 FROM XMLTABLE ('1 to 100000');
CREATE TABLE t2 (c1 NUMBER);
CREATE TABLE t3 (c1 NUMBER);
CREATE TABLE t4 (c1 NUMBER);

CREATE INDEX t3_x1 ON t3 (c1);
CREATE INDEX t4_f1 ON t4 (c1);

ALTER TABLE t1 ADD CONSTRAINT t1_pk PRIMARY KEY (c1);
ALTER TABLE t4 ADD CONSTRAINT t4_f1 FOREIGN KEY (c1) REFERENCES t1 (c1);

아래는 t2, t3, t4 테이블에 10만건을 입력한 결과다. 쿼리 2-1은 입력 작업에 2936개의 블록 I/O가 발생했다. 쿼리 2-2는 인덱스 유지를 위해 6538개(=9474-2936)의 블록 I/O가 추가로 발생했다. 쿼리 2-3은 부모 테이블에 대한 룩업 작업에 20만 개(=209K-9474)의 블록 I/O가 추가로 발생했다. t1_pk 인덱스가 2레벨이므로 입력 건수의 2배만큼 블록 I/O가 발생했고, 버퍼 피닝이 동작하지 않았다.

-- 2-1
INSERT INTO t2 SELECT ROWNUM FROM XMLTABLE ('1 to 100000');

-------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name                  | Starts | A-Rows | Buffers |
-------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT                    |                       |      1 |      0 |    2936 |
|   1 |  LOAD TABLE CONVENTIONAL            |                       |      1 |      0 |    2936 |
|   2 |   COUNT                             |                       |      1 |    100K|       3 |
|   3 |    COLLECTION ITERATOR PICKLER FETCH| XQSEQUENCEFROMXMLTYPE |      1 |    100K|       3 |
-------------------------------------------------------------------------------------------------

-- 2-2
INSERT INTO t3 SELECT ROWNUM FROM XMLTABLE ('1 to 100000');

-------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name                  | Starts | A-Rows | Buffers |
-------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT                    |                       |      1 |      0 |    9474 |
|   1 |  LOAD TABLE CONVENTIONAL            |                       |      1 |      0 |    9474 |
|   2 |   COUNT                             |                       |      1 |    100K|       3 |
|   3 |    COLLECTION ITERATOR PICKLER FETCH| XQSEQUENCEFROMXMLTYPE |      1 |    100K|       3 |
-------------------------------------------------------------------------------------------------

-- 2-3
INSERT INTO t4 SELECT ROWNUM FROM XMLTABLE ('1 to 100000');

-------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name                  | Starts | A-Rows | Buffers |
-------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT                    |                       |      1 |      0 |     209K|
|   1 |  LOAD TABLE CONVENTIONAL            |                       |      1 |      0 |     209K|
|   2 |   COUNT                             |                       |      1 |    100K|       3 |
|   3 |    COLLECTION ITERATOR PICKLER FETCH| XQSEQUENCEFROMXMLTYPE |      1 |    100K|       3 |
-------------------------------------------------------------------------------------------------


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

JPPD와 서브 쿼리 팩토링  (0) 2018.12.11
JPPD와 ROLLUP  (0) 2018.12.10
INDEX SCAN 방식에 따른 사용자 정의 함수  (0) 2018.12.07
TIMESTAMP 타입과 SYSTIMESTAMP 함수  (0) 2018.12.01
SQL 메타 데이터  (0) 2018.12.01
Posted by 정희락_