일반 적인 INSERT는 한건씩 처리하며 데이터를 삽입합니다.
PL/SQL을 사용하면 여러 행의 데이터를 절차적으로 처리할 수 있습니다.
테스트를 통해 확인해보겠습니다.
DB : Oracle 12.2.0.1
테스트 요약 : 각 테이블에 100만건의 데이터를 일반 INSERT와 BULK INSERT를 이용해서 삽입하고 비교
일반 INSERT
1.테이블 생성
CREATE TABLE BULKINS2 (A NUMBER, B NUMBER, C NUMBER);
2.데이터 삽입
BEGIN
FOR i IN 1..1000000 LOOP
INSERT INTO BULKINS2 VALUES (i, 10, 99);
END LOOP;
COMMIT;
END;
/
3.확인
SQL> select count(*) from BULKINS2;
COUNT(*)
----------
1000000
BULK INSERT
1.테이블 생성
CREATE TABLE BULKINS3 (A NUMBER, B NUMBER, C NUMBER);
2,데이터 삽입
PL/SQL 설명을 좀 하자면 TYPE 선언을 할 때 INDEX BY BINARY_INTERGER로 설정하여 인덱스 테이블 형식으로 선언하였습니다. 인덱스 테이블은 테이블의 각 요소가 정수값으로 색인되어 있는 테이블이고 테이블의 각 요소는 불연속적으로 저장되며 테이블의 최대크기를 설정하기 못합니다. 테이블의 인덱스에 대한 데이터형은 BINARY_INTERGER형이어야 합니다. 그래서 bulk_ins의 타입을 인덱스테이블로 설정하고 BINARY_INTERGER형으로 선언하였습니다.
그리고 FORALL 구문을 사용하여 한번에 INSERT를 수행합니다
DECLARE
TYPE bulk_ins IS TABLE OF BULKINS%ROWTYPE INDEX BY BINARY_INTEGER;
ysbae bulk_ins;
BEGIN
FOR i IN 1..1000000 LOOP
ysbae(i).A :=i;
ysbae(i).B :=10;
ysbae(i).C :=99;
END LOOP;
FORALL i in 1..1000000 INSERT INTO BULKINS3 VALUES ysbae(i);
COMMIT;
END;
/
출처 : https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=agapeuni&logNo=60096910378
출처 : https://docs.oracle.com/database/121/LNPLS/forall_statement.htm#LNPLS01321
3.확인
SQL> select count(*) from bulkins3;
COUNT(*)
----------
1000000
두 INSERT 간의 비교
v$sqlarea의 컬럼값들을 가져와서 서로의 차이를 비교해봅니다.
일반 INSERT의 경우에는 EXECUTIONS가 건수만큼 수행되었고, BULK INSERT는 1회 수행되었습니다.
수행시간과 CPU_TIME의 경우에는 BULK INSERT가 훨씬 리소스적으로 효율적으로 수행되었습니다.
USER_IO_WAIT_TIME의 경우에도 BULK INSERT의 경우에는 없는 반면 일반 INSERT의 경우에는 120214 micro seconds(0.120214초)의 wait time이 있었습니다.
즉, 상황이 대량의 INSERT를 해야하는 상황이면 BULK INSERT를 수행하면 효율이 높을 수 있을 것 같습니다. 하지만 PL/SQL을 작성해야 하므로 개발 능력이 필요하다는 단점도 존재하는 거 같네요..ㅎ
SQL> select sql_text,sql_id,sorts,fetches,executions,parse_calls,disk_reads,direct_writes,direct_Reads,buffer_gets,user_io_wait_time,rows_processed,cpu_time,elapsed_time,locked_total,pinned_total from v$sqlarea
where sql_id='7w1a9ab29a5c9'
or sql_id = '5txs62412trh7'
--where sql_text like '%INSERT%';
SQL_TEXT SQL_ID SORTS FETCHES EXECUTIONS PARSE_CALLS DISK_READS DIRECT_WRITES DIRECT_READS BUFFER_GETS USER_IO_WAIT_TIME ROWS_PROCESSED CPU_TIME ELAPSED_TIME LOCKED_TOTAL PINNED_TOTAL
----------------------------------------------- ------------- ---------- -------------- -------------------- ---------------------- -------------------- -------------------------- ------------------------ ---------------------- ---------------------------------- ---------------------------- ---------------- ------------------------ ------------------------ ------------------------
INSERT INTO BULKINS3 VALUES (:B1 ,:B2 ,:B3 ) 5txs62412trh7 0 0 1 0 0 0 0 23180 0 1000000 428729 748151 2 4
INSERT INTO BULKINS2 VALUES (:B1 , 10, 99) 7w1a9ab29a5c9 0 0 1000000 0 0 0 0 1038209 120214 1000000 9307335 15608531 2 1000003
2 rows selected.
출처 : https://positivemh.tistory.com/183
출처 : http://wiki.gurubee.net/pages/viewpage.action?pageId=3901299
'Oracle > 운영' 카테고리의 다른 글
SQL_MONITOR 사용법 (0) | 2021.11.20 |
---|---|
통계정보 복사하기 (partition table) (0) | 2021.11.19 |
통계정보 관련 딕셔너리 뷰 (0) | 2021.11.11 |
테이블 파티션 Split,Merge,Coalesce (0) | 2021.11.08 |
대용량 테이블 컬럼 순서 변경 테스트(12c new feature column visiable 기능 사용) (0) | 2021.11.03 |
댓글