지식

Mybatis 사용시 My-sql 대용량 데이터 Bulk Insert

애앨리 2021. 7. 29. 15:55

 

이번 프로젝트에서 Oracle -> mysql 로 대용량데이터 이관 하는 프로세스가 있어

작업중 이슈사항 정리 해본다.

 

구글링 해서 찾아보면

Loop를 이용해서 단건씩 Insert 하는 것 보다 Multi Value로 Insert 하면 성능이 월등하게 뛰어나다고 

 

예를들면

start transaction;

insert into tb_name (a, b, c) values (1, 2, 3);

insert into tb_name (a, b, c) values (1, 2, 3);

insert into tb_name (a, b, c) values (1, 2, 3);

commit transaction;

 

이것보다 

 

insert into tb_name (a, b, c)

values (1, 2, 3), (4, 5, 6), (7, 8, 9);

 

이렇게 하라고 

 

스프링 + Mybatis 프레임웤 에서는

 

<insert id="insertResultAll" parameterType="java.util.List">

    insert into tb_name (a, b, c)

    values

    <foreach collection="list" item="item" index="index" open="(" close=")" separator=",">

    #{a},#{b},#{v}

    </foreach>

</insert>

 

이런식으로 foreach 를 쓰라고 한다. 근데 이게 100만건을 넘어가는 순간 저 Loop 만드는데 시간이 더걸린다.

그래서 최종적으로 선택한 방법

 

Service 단에서 sql문을 String 형으로 만든 다음에 Dao에  던졌다

 

for (Data data : dataList) {
sqlStr = "'"+data.getData+"','"

 

 

 

<insert id="insertResultAll" parameterType="String">

    insert into tb_name (a, b, c)

    values (

    ${sqlText}

    )

</insert>

 

#으로 하면 SQL DB 실행 시에 데이터로 바인딩

ex) strText = "데이터" 일경우 #{srtText} 는 '데이터'


$으로 하면 SQL 쿼리문 로드시에 데이터 바인딩

ex) strText = "데이터" 일경우 ${srtText} 는 데이터

이렇게 처리 되기때문에 $의 경우 Sql injection에 취약하다.

가급적이면 않쓰는게 좋음!

 

필자는 내부서버에서 만 쓰는 서비스라 사용