Java에서 Oracle로 대량 삽입
Oracle에 많은 작은 행을 빠르게 삽입해야 합니다. (5개 필드)
MySQL에서는 삽입물을 100개의 그룹으로 나눈 다음 100개의 삽입물 그룹마다 하나의 삽입문을 사용합니다.
그러나 Oracle의 경우 매스 삽입(1000-30000 범위)이 너무 느리다는 사용자 의견이 있습니다.
자바에서 오라클로 프로그램 삽입 속도를 높이기 위해 사용할 수 있는 유사한 트릭이 있습니까?
Spring의 DAO 모듈을 사용하여 많은 행을 일괄 삽입할 수 있습니다.
Order 개체 컬렉션을 한 번의 업데이트로 데이터베이스에 삽입하는 예:
public class OrderRepositoryImpl extends SimpleJdbcDaoSupport implements
OrderRepository {
private final String saveSql = "INSERT INTO orders(userid, username, coffee, coffeename, amount) "
+ "VALUES(?, ?, ?, ?, ?)";
public void saveOrders(final Collection<Order> orders) {
List<Object[]> ordersArgumentList = new ArrayList<Object[]>(orders
.size());
Object[] orderArguments;
for (Order order : orders) {
orderArguments = new Object[] { order.getUserId(),
order.getUserName(), order.getCoffe(),
order.getCoffeeName(), order.getAmount() };
ordersArgumentList.add(orderArguments);
}
getSimpleJdbcTemplate().batchUpdate(saveSql, ordersArgumentList);
}
}
이러한 레코드를 데이터베이스에 전달하는 방법에 대해 말하지 않습니다.가장 좋은 방법은 어레이를 사용하는 것입니다. 이렇게 하면 Oracle의 풍부한 FORNITY를 모든 대량 작업에 사용할 수 있습니다.
이 예제 패키지에는 두 가지 절차가 있습니다.하나는 T23 레코드 모음(5개의 숫자 열로 구성된 테이블)을 채우는 것이고 하나는 배열을 사용하여 해당 테이블에 레코드를 대량으로 삽입하는 것입니다.
SQL> create or replace package p23 as
2 type t23_nt is table of t23%rowtype;
3 function pop_array ( p_no in number )
4 return t23_nt;
5 procedure ins_table ( p_array in t23_nt );
6 end p23;
7 /
Package created.
SQL> create or replace package body p23 as
2
3 function pop_array ( p_no in number )
4 return t23_nt
5 is
6 return_value t23_nt;
7 begin
8 select level,level,level,level,level
9 bulk collect into return_value
10 from dual
11 connect by level <= p_no;
12 return return_value;
13 end pop_array;
14
15 procedure ins_table
16 ( p_array in t23_nt )
17 is
18 s_time pls_integer;
19 begin
20
21 s_time := dbms_utility.get_time;
22
23 forall r in p_array.first()..p_array.last()
24 insert into t23
25 values p_array(r);
26
27 dbms_output.put_line('loaded '
28 ||to_char(p_array.count())||' recs in '
29 ||to_char(dbms_utility.get_time - s_time)
30 ||' csecs');
31 end ins_table;
32 end p23;
33 /
Package body created.
SQL>
다음은 일부 샘플 실행의 출력입니다.
SQL> declare
2 l_array p23.t23_nt;
3 begin
4 l_array := p23.pop_array(500);
5 p23.ins_table(l_array);
6 l_array := p23.pop_array(1000);
7 p23.ins_table(l_array);
8 l_array := p23.pop_array(2500);
9 p23.ins_table(l_array);
10 l_array := p23.pop_array(5000);
11 p23.ins_table(l_array);
12 l_array := p23.pop_array(10000);
13 p23.ins_table(l_array);
14 l_array := p23.pop_array(100000);
15 p23.ins_table(l_array);
16 end;
17 /
loaded 500 recs in 0 csecs
loaded 1000 recs in 0 csecs
loaded 2500 recs in 0 csecs
loaded 5000 recs in 1 csecs
loaded 10000 recs in 1 csecs
loaded 100000 recs in 15 csecs
PL/SQL procedure successfully completed.
SQL>
SQL> select count(*) from t23
2 /
COUNT(*)
----------
119000
SQL>
0.15초 안에 100,000개의 레코드를 삽입하는 것은 가장 까다로운 사용자를 제외한 모든 사용자를 만족시켜야 한다고 생각합니다.문제는 삽입물에 어떻게 접근하느냐입니다.
현재 MySQL은 Oracle이므로 MySQL에 유지하는 것이 더 간단한 솔루션일 수 있습니다.
그렇지 않은 경우에는 삽입 그룹을 시작하기 전에 트랜잭션이 시작되었는지 확인해야 합니다. 그룹이 완료되면 트랜잭션을 커밋하고 다음 삽입 그룹에 대해 새 트랜잭션을 시작합니다.
또한 삽입 시간을 지연시킬 수 있는 불필요한 인덱스 정의도 확인합니다.
업데이트됨...
대량 삽입은 ETL(Extract Transform Load)의 마지막 단계를 의미하므로 펜타호 주전자나 탤런트 스튜디오와 같은 자바 기반 ETL 도구를 사용하는 것을 고려해 본 적이 있습니까?
Pentaho는 Oracle Bulk 로딩 기능을 여기에 설명합니다.
빠른 구글은 또한 Talend가 Oracle 대량 로딩을 지원한다는 예비 증거를 보여줍니다.
먹어봐.
public Boolean inserTable(String fileName) {
logger.info("Begin - " + this.getClass().getSimpleName() + "." + "inserTable");
logger.info("File : " + fileName);
try (Connection conn1 = jdbcTemplate.getDataSource().getConnection();) {
OracleConnection conn = ( OracleConnection ) conn1.getMetaData().getConnection();
ScriptRunner sr = new ScriptRunner(conn);
StringBuilder sBuffer = new StringBuilder();
StringBuffer sb=new StringBuffer();
String query = "Insert into TABLE_DATA (ID, DATA1, DATECREATED, CREATEDBY) Values ";
String line = "";
//Creating a reader object
BufferedReader br = new BufferedReader(new FileReader(fileName),1024 * 1024 );
while ((line = br.readLine()) != null) {
//logger.info("Leyo linea : " + line);
sb.append(query.concat("(").concat("TABLE_DATA_SQ.NEXTVAL,").concat(line.substring(0,6)).concat(",").concat("sysdate,").concat("'BDVENLINEA'").concat(");"));
sb.append("\n");
}
sb.append("commit;");
Reader reader = new StringReader(sb.toString());
//Running the script
sr.runScript(reader);
reader.close();
br.close();
return true;
} catch (FileNotFoundException e) {
logger.error(e.getMessage(), e);
throw new TechnicalException(e, e.getMessage());
} catch (SQLException e) {
e.printStackTrace();
throw new TechnicalException(e, e.getMessage());
} catch (IOException e) {
e.printStackTrace();
throw new TechnicalException(e, e.getMessage());
} finally {
logger.info("End - " + this.getClass().getSimpleName() + "." + "inserTable");
}
}
언급URL : https://stackoverflow.com/questions/2716818/bulk-insert-from-java-into-oracle
'itsource' 카테고리의 다른 글
FastAPI에서 오류가 발생합니다(ASGI 앱 로드 오류).모듈 "api"를 가져올 수 없습니다.) (0) | 2023.08.15 |
---|---|
jQuery 대화상자의 버튼을 기능에서 비활성화하려면 어떻게 해야 합니까? (0) | 2023.08.15 |
PowerShell ISE 내의 함수 호출 (0) | 2023.08.15 |
쿼리 결과에서 실제 날짜에 이전 날짜의 값 추가 (0) | 2023.08.15 |
내 테이블만 표시하도록 SQL 개발자를 필터링하는 방법은 무엇입니까? (0) | 2023.08.15 |