У меня есть задание вставить 8 миллионов строк в таблицу базы данных oracle. Я масштабировал работу на 8 ядрах ЦП, вот пример кода:
final long start = System.currentTimeMillis();
final int batchSize = 800000;
final int nCore = Runtime.getRuntime().availableProcessors();
final int batchPerCore = batchSize / nCore;
final CountDownLatch taskCountDown = new CountDownLatch(nCore);
final CountDownLatch kickoffLatch = new CountDownLatch(1);
final ExecutorService es = Executors.newFixedThreadPool(nCore);
Class.forName("oracle.jdbc.driver.OracleDriver");
for (int n = 0; n < nCore; n++) {
es.submit(() -> {
log.info("Thread {} starts working on {} insertion jobs.", Thread.currentThread().getName(), batchPerCore);
try (Connection conn = DriverManager.getConnection(DB_URL, USER_NAME, PASSWORD)) {
Assert.assertNotNull("connection established", conn);
conn.setAutoCommit(false);
PreparedStatement pstmt = conn.prepareStatement(PREP_STATEMENT);
for (int i = 0; i < batchPerCore; i++) {
initPrepTranStatement(pstmt);
pstmt.addBatch();
}
int[] resultTran = pstmt.executeBatch();
Assert.assertEquals(resultTran.length, batchPerCore);
conn.commit();
log.info("Thread {} completed its job!", Thread.currentThread().getName());
taskCountDown.countDown();
} catch (SQLException e) {
e.printStackTrace();
}
});
} // ~ for ~
es.shutdown();
kickoffLatch.countDown();
taskCountDown.await();
log.info("It takes {} milliseconds to complete all {} tasks for {} insertions each. ",
(System.currentTimeMillis()-start), nCore, batchPerCore);
в процессе выполнения, он показывает 3 задачи, выполненные при выполнении курсов в 14:09, но другие еще ожидающие на момент написания статьи (15:29).
Вот журнал:
Apr 27, 2020 1:25:17 PM com.db.loader.DBFlexDataLoadingPerfTest lambda$4
INFO: Thread pool-1-thread-7 starts working on 100000 insertion jobs.
Apr 27, 2020 1:25:17 PM com.db.loader.DBFlexDataLoadingPerfTest lambda$4
INFO: Thread pool-1-thread-2 starts working on 100000 insertion jobs.
Apr 27, 2020 1:25:17 PM com.db.loader.DBFlexDataLoadingPerfTest lambda$4
INFO: Thread pool-1-thread-5 starts working on 100000 insertion jobs.
Apr 27, 2020 1:25:17 PM com.db.loader.DBFlexDataLoadingPerfTest lambda$4
INFO: Thread pool-1-thread-8 starts working on 100000 insertion jobs.
Apr 27, 2020 1:25:17 PM com.db.loader.DBFlexDataLoadingPerfTest lambda$4
INFO: Thread pool-1-thread-4 starts working on 100000 insertion jobs.
Apr 27, 2020 1:25:17 PM com.db.loader.DBFlexDataLoadingPerfTest lambda$4
INFO: Thread pool-1-thread-3 starts working on 100000 insertion jobs.
Apr 27, 2020 1:25:17 PM com.db.loader.DBFlexDataLoadingPerfTest lambda$4
INFO: Thread pool-1-thread-6 starts working on 100000 insertion jobs.
Apr 27, 2020 1:25:17 PM com.db.loader.DBFlexDataLoadingPerfTest lambda$4
INFO: Thread pool-1-thread-1 starts working on 100000 insertion jobs.
Apr 27, 2020 2:09:53 PM com.db.loader.DBFlexDataLoadingPerfTest lambda$4
INFO: Thread pool-1-thread-4 completed its job!
Apr 27, 2020 2:09:53 PM com.db.loader.DBFlexDataLoadingPerfTest lambda$4
INFO: Thread pool-1-thread-6 completed its job!
Apr 27, 2020 2:09:53 PM com.db.loader.DBFlexDataLoadingPerfTest lambda$4
INFO: Thread pool-1-thread-7 completed its job!
Использование DriverManager в этом случае не очень хорошая идея, тем не менее, я должен был использовать реализацию DataSource это не имеет значения или не влияет на цель этого теста.
Учитывая, что все задачи одинаковы с точки зрения характера работы и способа выполнения, я не могу понять, почему некоторые серьезно отстают от других, и, скорее всего, они просто висят там.
Конкретные аргументы JVM не заданы. Машина Windows 10 pro, с 8-ядерным i7-6700 и 32G RAM.