본문 바로가기

프로그래밍/이것저것 일하면서

[데이터베이스/오라클] 대량 insert 속도 개선

반응형

요즘 푸시 발송 속도 개선을 하고 있는데, FCM 발송 후 결과 저장이나 잘못된 토큰 삭제 처리에서 병목이 생기는 것을 확인하였다. 그래서 사용자의 푸시 '알림함'에 대량 insert 하는 부분을 개선하고자 오라클 다중 insert 속도를 개선하는 방법을 찾아보았다.

### 기존

INSERT INTO SOME_TABLE (col1, col2 ..)
VALUES (#{val1}, #{val2} ..);

 

### 1차 수정

하나의 commit으로 처리될 수 있도록 묶었다. (참고로 spring + mybatis 사용하여 처리 중)

로컬 디비로 1000건 insert 테스트 시 26초가 나왔다.

BEGIN

INSERT INTO SOME_TABLE (col1, col2 ..)
VALUES (#{val1}, #{val2} ..);

INSERT INTO SOME_TABLE (col1, col2 ..)
VALUES (#{val1}, #{val2} ..);

INSERT INTO SOME_TABLE (col1, col2 ..)
VALUES (#{val1}, #{val2} ..);

END;

-- commit

 

### 2차 수정

아래처럼 INSERT INTO ... SELECT FROM DUAL UNION ALL ... 구문으로 수정했습니다.

INSERT INTO SOME_TABLE (col1, col2 ..)
SELECT SOME_SEQUENCE.nextval, #{val2} .. FROM DUAL UNION ALL
SELECT SOME_SEQUENCE.nextval, #{val2} .. FROM DUAL UNION ALL
SELECT SOME_SEQUENCE.nextval, #{val2} .. FROM DUAL;

그런데 시퀀스 사용에 문제가 있네요. 찾아보니 시퀀스의 사용 제약 중 UNION과는 사용할 수 없다는 것이 있었습니다.

 

### 3차 수정

시퀀스 오류를 회피하기 위해 시퀀스를 반환하는 함수를 생성하였습니다. 실행이 잘 되고, 1000건 insert 실행 속도가 약 1/5로 줄어들었습니다. 해피엔딩입니다.

INSERT INTO SOME_TABLE (col1, col2 ..)
SELECT FN_GET_NEXT_ID(), #{val2} .. FROM DUAL UNION ALL
SELECT FN_GET_NEXT_ID(), #{val2} .. FROM DUAL UNION ALL
SELECT FN_GET_NEXT_ID(), #{val2} .. FROM DUAL;

 

 

## 참고: 시퀀스를 반환하는 함수

create or replace
    FUNCTION FN_GET_NEXT_SOME_ID RETURN NUMBER AS
    num NUMBER;
BEGIN
    SELECT MYUSER.SEQ_SOME_ID.nextval
    INTO num
    FROM dual;
    return num;
END FN_GET_NEXT_SOME_ID;
반응형

개발자가 그리는 인스타툰 팔로우하세요!