在Java中优化Oracle的copyTable函数
我喜欢将一些表复制到Oracle数据库中,因此我编写了以下Java方法:在Java中优化Oracle的copyTable函数,java,oracle,performance,dynamic-sql,Java,Oracle,Performance,Dynamic Sql,我喜欢将一些表复制到Oracle数据库中,因此我编写了以下Java方法: public static int copyTable (String cmdSelect, String cmdInsert, String sourceURL) throws SQLException { int rowCount = 0; try { Connection conOra = DriverManager.getConnection("jdbc:default:
public static int copyTable (String cmdSelect, String cmdInsert, String sourceURL) throws SQLException {
int rowCount = 0;
try {
Connection conOra = DriverManager.getConnection("jdbc:default:connection:");
Connection conGauss = DriverManager.getConnection(sourceURL, "username", "password");
PreparedStatement sthSel = conGauss.prepareStatement(cmdSelect);
PreparedStatement sthIns = conOra.prepareStatement(cmdInsert);
ResultSet rs = sthSel.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
while ( rs.next() ) {
for( int c = 1; c <= rsmd.getColumnCount(); c++ ) {
sthIns.setObject(c, rs.getObject(c), rsmd.getColumnType(c), rsmd.getScale(c));
}
sthIns.addBatch();
rowCount++;
if (rowCount % 10000 == 0) {
sthIns.executeBatch();
}
}
sthIns.executeBatch();
rs.close();
sthSel.close();
sthIns.close();
conGauss.close();
conOra.close();
}
catch (SQLException e) {
throw e;
}
return rowCount;
}
我这样称呼它:
DECLARE
cmdSelect VARCHAR2(1000) := 'SELECT NRID, NEID, NRNAME, NR_NAME, NBTYPE, NETYPE, GNODEBID, INVALIDTIME, OBJECTSTATUS FROM D_NR';
cmdInsert VARCHAR2(1000) := 'INSERT INTO D_NR_COPY (NRID, NEID, NRNAME, NR_NAME, NBTYPE, NETYPE, GNODEBID, INVALIDTIME, OBJECTSTATUS) VALUES (?,?,?,?,?,?,?,?,?)';
ret INTEGER;
BEGIN
ret := copyTable(cmdSelect, cmdInsert, 'some URL');
DBMS_OUTPUT.PUT_LINE ( 'ret = ' || ret );
COMMIT;
END;
我的第一次测试工作正常,程序正常。但我有点担心性能,有些桌子会很大。我对Java一无所知
我是否必须循环
for(int c=1;cJDBC驱动程序通常获取多行。默认行数取决于驱动程序(例如Oracles的JDBC驱动程序的默认行数为10)。您可以通过Statement.getFetchSize()检查默认的获取大小,并通过Statement.setFetchSize(int)增加它。请注意,获取大小只是JDBC驱动程序的提示,它可能会忽略或覆盖该大小。如果应该忽略设置的获取大小,我建议检查JDBC驱动程序的文档
虽然理论上是可能的(取决于JDBC驱动程序的实现),对ResultSetMetaData方法的调用不太可能触发对DB的额外调用。更有可能的是,整个元数据已经在内存中。在这种情况下,不需要在此处进行优化。您不能创建到源数据库的数据库链接吗?使用DB链接的单次插入选择sql将非常有用faster@SayanMalakshinov否,数据库链接到非Oracle是不可能的。您可以使用“Oracle数据库网关for ODBC”,但是源数据库是华为的SDB,我们的Oracle运行在Redhat Linux上。由于特朗普/美国的禁令,华为可能不会在Redhat上为其数据库提供ODBC驱动程序,这同样适用于Windows。我们的Oracle迁移到另一个Linux(如Suse Linux)也没有选择。
DECLARE
cmdSelect VARCHAR2(1000) := 'SELECT NRID, NEID, NRNAME, NR_NAME, NBTYPE, NETYPE, GNODEBID, INVALIDTIME, OBJECTSTATUS FROM D_NR';
cmdInsert VARCHAR2(1000) := 'INSERT INTO D_NR_COPY (NRID, NEID, NRNAME, NR_NAME, NBTYPE, NETYPE, GNODEBID, INVALIDTIME, OBJECTSTATUS) VALUES (?,?,?,?,?,?,?,?,?)';
ret INTEGER;
BEGIN
ret := copyTable(cmdSelect, cmdInsert, 'some URL');
DBMS_OUTPUT.PUT_LINE ( 'ret = ' || ret );
COMMIT;
END;