Я должен вставить пару сотен миллионов записей в mysql дб. Я - пакет, вставляющий его 1 миллион за один раз. См. мой код ниже. Это, кажется, медленно. Там какой-либо путь состоит в том, чтобы оптимизировать его?
try {
// Disable auto-commit
connection.setAutoCommit(false);
// Create a prepared statement
String sql = "INSERT INTO mytable (xxx), VALUES(?)";
PreparedStatement pstmt = connection.prepareStatement(sql);
Object[] vals=set.toArray();
for (int i=0; i<vals.length; i++) {
pstmt.setString(1, vals[i].toString());
pstmt.addBatch();
}
// Execute the batch
int [] updateCounts = pstmt.executeBatch();
System.out.append("inserted "+updateCounts.length);
Вы можете вставлять несколько строк одним оператором insert, выполнение нескольких тысяч за раз может значительно ускорить работу, то есть вместо того, чтобы делать, например. 3 вставки вида INSERT INTO tbl_name (a,b,c) VALUES(1,2,3);
, вы делаете INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(1,2,3),(1,2,3);
(Это может быть JDBC . addBatch() теперь делает подобную оптимизацию - хотя раньше mysql addBatch был совершенно неоптимизирован и просто выдавал отдельные запросы - я не знаю, так ли это в последних драйверах)
Если вам действительно нужна скорость, загрузите данные из файла с разделителями-запятыми с помощью LOAD DATA INFILE, мы получаем примерно 7-8-кратное ускорение по сравнению с десятками миллионов вставок.
Если:
Тогда ALTER TABLE tbl_name DISABLE KEYS
может значительно улучшить скорость вставки. Когда вы закончите, запустите ALTER TABLE tbl_name ENABLE KEYS
, чтобы начать создание индексов, что может занять некоторое время, но не так долго, как делать это для каждой вставки.
Вы можете попробовать использовать объект DDBulkLoad.
// Get a DDBulkLoad object
DDBulkLoad bulkLoad = DDBulkLoadFactory.getInstance(connection);
bulkLoad.setTableName(“mytable”);
bulkLoad.load(“data.csv”);