Apache Tomcat JDBC Connection Pool плохая производительность при пакетной \ групповой вставке
Недавно я включил в свое приложение пул соединений JDBC Apache Tomcat (используя MySQL DB). Я пытался использовать Apache DBCP раньше, но мне не понравились его результаты, и реализация tomcat, казалось, соответствовала моим потребностям, даже несмотря на то, что я запускаю отдельное приложение Java и вообще не использую tomcat.
Недавно я столкнулся с огромной проблемой производительности при выполнении запросов пакетной (или групповой) вставки.
У меня есть поток, в котором я вставляю ~2500 записей в таблицу в пакетном режиме. При использовании пула соединений jdbc это занимает вечность по сравнению с несколькими секундами при возврате к открытию соединения для каждого запроса (без объединения в пул).
Я написал небольшое приложение, которое вставляет 30 строк в одну таблицу. Это занимает 12 секунд, когда пул, и ~ 800 миллисекунд, когда не пул.
До использования пула соединений я использовал com.mysql.jdbc.jdbc2.optional.MysqlDataSource
как мой источник данных. Соединение было настроено с помощью следующей строки:
dataSource.setRewriteBatchedStatements(true);
Я совершенно уверен, что в этом основное различие между двумя подходами, но не смог найти эквивалентный параметр в jdbc-pool.
1 ответ
Драйвер MySql JDBC не поддерживает пакетные операции. RewriteBatchedStatement - лучшее, что вы можете получить. Вот код из mysql PreparedStatement.java:
try {
statementBegins();
clearWarnings();
if (!this.batchHasPlainStatements && this.connection.getRewriteBatchedStatements()) {
if (canRewriteAsMultiValueInsertAtSqlLevel()) {
return executeBatchedInserts(batchTimeout);
}
if (this.connection.versionMeetsMinimum(4, 1, 0) && !this.batchHasPlainStatements && this.batchedArgs != null
&& this.batchedArgs.size() > 3 /* cost of option setting rt-wise */) {
return executePreparedBatchAsMultiStatement(batchTimeout);
}
}
return executeBatchSerially(batchTimeout);
} finally {
this.statementExecuting.set(false);
clearBatch();
}
Это одна из причин, почему я не люблю MySql и предпочитаю Postgres
РЕДАКТИРОВАТЬ:
Вы должны объединить пул соединений, пакетную операцию и опцию RewriteBatchedStatement. Вы можете установить опцию RewriteBatchedStatement через параметр URL-адреса jdbc: jdbc:mysql://localhost:3307/mydb?rewriteBatchedStatements=true