Obwohl die Frage lautet, wie man mithilfe von JDBC effizient in Oracle einfügt , spiele ich derzeit mit DB2 (auf IBM Mainframe). Das konzeptionelle Einfügen wäre ähnlich, sodass es hilfreich sein könnte, meine Metriken dazwischen zu sehen
Hier gehen die Metriken
1) Jeweils einen Datensatz einfügen
public void writeWithCompileQuery(int records) {
PreparedStatement statement;
try {
Connection connection = getDatabaseConnection();
connection.setAutoCommit(true);
String compiledQuery = "INSERT INTO TESTDB.EMPLOYEE(EMPNO, EMPNM, DEPT, RANK, USERNAME)" +
" VALUES" + "(?, ?, ?, ?, ?)";
statement = connection.prepareStatement(compiledQuery);
long start = System.currentTimeMillis();
for(int index = 1; index < records; index++) {
statement.setInt(1, index);
statement.setString(2, "emp number-"+index);
statement.setInt(3, index);
statement.setInt(4, index);
statement.setString(5, "username");
long startInternal = System.currentTimeMillis();
statement.executeUpdate();
System.out.println("each transaction time taken = " + (System.currentTimeMillis() - startInternal) + " ms");
}
long end = System.currentTimeMillis();
System.out.println("total time taken = " + (end - start) + " ms");
System.out.println("avg total time taken = " + (end - start)/ records + " ms");
statement.close();
connection.close();
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
}
}
Die Metriken für 100 Transaktionen:
each transaction time taken = 123 ms
each transaction time taken = 53 ms
each transaction time taken = 48 ms
each transaction time taken = 48 ms
each transaction time taken = 49 ms
each transaction time taken = 49 ms
...
..
.
each transaction time taken = 49 ms
each transaction time taken = 49 ms
total time taken = 4935 ms
avg total time taken = 49 ms
Die erste Transaktion wird ausgeführt, 120-150ms
die für die Analyse der Abfrage und die anschließende Ausführung vorgesehen ist. Die nachfolgenden Transaktionen werden nur ausgeführt 50ms
. (Was immer noch hoch ist, aber meine Datenbank befindet sich auf einem anderen Server (ich muss das Netzwerk beheben))
2) Mit Einfügen in eine Charge (effiziente) - erreicht durchpreparedStatement.executeBatch()
public int[] writeInABatchWithCompiledQuery(int records) {
PreparedStatement preparedStatement;
try {
Connection connection = getDatabaseConnection();
connection.setAutoCommit(true);
String compiledQuery = "INSERT INTO TESTDB.EMPLOYEE(EMPNO, EMPNM, DEPT, RANK, USERNAME)" +
" VALUES" + "(?, ?, ?, ?, ?)";
preparedStatement = connection.prepareStatement(compiledQuery);
for(int index = 1; index <= records; index++) {
preparedStatement.setInt(1, index);
preparedStatement.setString(2, "empo number-"+index);
preparedStatement.setInt(3, index+100);
preparedStatement.setInt(4, index+200);
preparedStatement.setString(5, "usernames");
preparedStatement.addBatch();
}
long start = System.currentTimeMillis();
int[] inserted = preparedStatement.executeBatch();
long end = System.currentTimeMillis();
System.out.println("total time taken to insert the batch = " + (end - start) + " ms");
System.out.println("total time taken = " + (end - start)/records + " s");
preparedStatement.close();
connection.close();
return inserted;
} catch (SQLException ex) {
System.err.println("SQLException information");
while (ex != null) {
System.err.println("Error msg: " + ex.getMessage());
ex = ex.getNextException();
}
throw new RuntimeException("Error");
}
}
Die Metriken für einen Stapel von 100 Transaktionen sind
total time taken to insert the batch = 127 ms
und für 1000 Transaktionen
total time taken to insert the batch = 341 ms
Daher werden 100 Transaktionen ~5000ms
(mit jeweils einem Trxn) auf ~150ms
(mit einem Stapel von 100 Datensätzen) reduziert .
HINWEIS - Ignoriere mein Netzwerk, das sehr langsam ist, aber die Metrikwerte wären relativ.