Я пытаюсь улучшить производительность своего Java-приложения, и в данный момент я концентрируюсь на одном конечном пункте, который должен вставить большой объем данных в mysql.
Я использую простой JDBC с драйвером клиента MariaDB Java:
try (PreparedStatement stmt = connection.prepareStatement(
"INSERT INTO data (" +
"fId, valueDate, value, modifiedDate" +
") VALUES (?,?,?,?)") {
for (DataPoint dp : datapoints) {
stmt.setLong(1, fId);
stmt.setDate(2, new java.sql.Date(dp.getDate().getTime()));
stmt.setDouble(3, dp.getValue());
stmt.setDate(4, new java.sql.Date(modifiedDate.getTime()));
stmt.addBatch();
}
int[] results = statement.executeBatch();
}
Из заполнения новой БД из выгруженных файлов я знаю, что max_allowed_packet
важен, и у меня установлено значение 536 870 912 байт.
В https://dev.mysql.com/doc/refman/5.7/en/insert-optimization.html говорится, что:
Если вы вставляете много строк из одного и того же клиента одновременно,
используйте операторы INSERT с несколькими списками VALUES, чтобы вставить несколько
строки одновременно. Это значительно быстрее (во многих случаях быстрее
случаи), чем использование отдельных однорядных операторов INSERT. Если ты
добавив данные в непустую таблицу, вы можете настроить
переменная bulk_insert_buffer_size , чтобы сделать вставку данных еще быстрее.
См. Раздел 5.1.7, «Системные переменные сервера» .
На моих БД установлено 8 МБ
Я также читал о key_buffer_size
(в настоящее время установлено значение 16 МБ).
Я обеспокоен тем, что этих двух последних может быть недостаточно. Я могу сделать некоторые грубые вычисления на входе JSON для этого алгоритма, потому что он выглядит примерно так:
[{"actualizationDate":null,"data":[{"date":"1999-12-31","value":0},
{"date":"2000-01-07","value":0},{"date":"2000-01-14","value":3144},
{"date":"2000-01-21","value":358},{"date":"2000-01-28","value":1049},
{"date":"2000-02-04","value":-231},{"date":"2000-02-11","value":-2367},
{"date":"2000-02-18","value":-2651},{"date":"2000-02-25","value":-
393},{"date":"2000-03-03","value":1725},{"date":"2000-03-10","value":-
896},{"date":"2000-03-17","value":2210},{"date":"2000-03-24","value":1782},
и похоже, что 8МБ, настроенный для bulk_insert_buffer_size
, может быть легко превышен, если не key_buffer_size
.
Но в документации по MySQL упоминаются только таблицы MyISAM
движка, и в настоящее время я использую InnoDB
таблицы.
Я могу настроить некоторые тесты, но было бы хорошо знать, как это сломается или ухудшится, если вообще.
[ПРАВИТЬ] У меня есть --rewriteBatchedStatements=true
. На самом деле вот моя строка подключения:
jdbc:p6spy:mysql://myhost.com:3306/mydb\
?verifyServerCertificate=true\
&useSSL=true\
&requireSSL=true\
&cachePrepStmts=true\
&cacheResultSetMetadata=true\
&cacheServerConfiguration=true\
&elideSetAutoCommits=true\
&maintainTimeStats=false\
&prepStmtCacheSize=250\
&prepStmtCacheSqlLimit=2048\
&rewriteBatchedStatements=true\
&useLocalSessionState=true\
&useLocalTransactionState=true\
&useServerPrepStmts=true
(из https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration)