반응형
요즘 푸시 발송 속도 개선을 하고 있는데, 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;
반응형
'프로그래밍 > 이것저것 일하면서' 카테고리의 다른 글
프로그램 버그, 고치는 것만큼 중요한 버그 리포트 작성과 공유 (0) | 2023.03.30 |
---|---|
@Param 어노테이션, MyBatis와 Spring Data 헷갈리지 말자 (0) | 2023.03.27 |
[데이터베이스] FK 쓸까, 말까? 오늘 외래키를 삭제한 이유 (0) | 2023.02.27 |
[오라클] 시퀀스, sysdate 등을 조회할 때 `FOM DUAL`을 쓰는 이유 (0) | 2023.02.27 |
특정 아이피의 VIP(Virtual IP) 여부를 확인하는 방법 (0) | 2023.02.27 |