by 나도개발자다! [Oracle 에러코드] 대량 insert select [2016.03.01 09:24:36]
제가 대량의 데이터를 복사하고싶은데요
즉슨
1. 다른유저의 데이터를 select 해서 rs(resultset) 와 rsmd(resultsetmetadata)등을 통해 데이터를 읽어와
제가 접속해있는 유저로 insert를 하려고합니다.
그런데 복사까진 잘되는데
100만건의 데이터를 하고싶습니다.
1테이블에 100개의 칼럼 100자 이상 한칼럼당 10000의 데이터로 해서 100만건입니다.
addBatch(물론 이건 속도라곤 함ㅠ)부터 메모리 줄일수 있는건 다해봤는데 최대 40000만건 이상 들어가질않고
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
이게 떠버리고 마네요
메모리를 효율적으로 관리하고싶습니다. 물론 뭐 스트링을 스트링버퍼로 바꾼다고 그게 문제가 아닌것같고.
무슨 방법이 없을까욘??
자바를 말씀하시는 것이라면,
ResultSet 객체의 인스턴스 rs를 계속 사용해야 하는 것이라면 임의로 비울 수 없습니다.
아시겠지만 rs.close()를 하면 계속 쓸 수 없고.. 분할하여 인서트 하는 것이 최선일 것 같습니다.
근데.. addBatch를 쓰신다면 PreparedStatement를 쓴다는 것 같은데, rsmd도 일회성일 것 같고,
메모리는 rs가 아닌 PreparedStatement쪽 메모리 초과 아닌가용? @.@)?
PreparedStatement는 말씀하신 것처럼 너무 많이 담으면 같은 오류가 발생합니다.
중간 중간에 executeBatch()로 처리를 해줘야 합니다.
1. 다른유저의 데이터를 select 해서 rs(resultset) 와 rsmd(resultsetmetadata)등을
통해 데이터를 읽어와제가 접속해있는 유저로 insert를 하려고합니다.
--> 다른유저의 데이타를 SQL로 처리가 가능하다면
insert into 나의오너.kkk
select *
from 다른사람오너.kkk
where ....
and....
즉 DB TO DB 개념으로 처리하는 프로그램으로 유도해 보시고
만약 다른사용자의 데이타를 많이 가공하여 생성(쿼리로처리 불가시)하는 데이타라고 가졍하면
TEMP성(현재접속한테이블과 유사하게 생성) 테이블을 생성하여 무작위로 INSERT처리합니다.
즉 TEMP성 테이블(현재접속한테이블과 유사하게 생성) 은 UUID 를 적용하고
addBatch()로 아무 조건없이 생성할 수있도록 처리합니다.
이후 TEMP성 테이블과 현재 접속한 테이블을 JOIN하여 일괄 처리합니다.
merge로 처리하든 ....
이후 다음에 또 처리할때는 반드시 TEMP성테이블 데이타를 삭제한후 앞의 처리방법으로 다시하면
문제가 되지 않을것입니다.
현재 처리하는 방법은 어쩔수 없이 많은 데이타를 rs()에 가져와서 처리하게 됨으로서
톰켓이나 WAS의 메모리 full이 발생하게 될것입니다.
다양한 처리방법은 있겠지만 더 좋은 솔루션은 다은 사용자에게서.....