JDBC пакетная производительность вставки

Я должен вставить пару сотен миллионов записей в 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);
64
задан BalusC 7 June 2010 в 21:25
поделиться

3 ответа

Вы можете вставлять несколько строк одним оператором 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-кратное ускорение по сравнению с десятками миллионов вставок.

13
ответ дан 24 November 2019 в 15:36
поделиться

Если:

  1. Это новая таблица, или количество вставляемых данных больше, чем уже вставленных
  2. На таблице есть индексы
  3. Вам не нужен другой доступ к таблице во время вставки

Тогда ALTER TABLE tbl_name DISABLE KEYS может значительно улучшить скорость вставки. Когда вы закончите, запустите ALTER TABLE tbl_name ENABLE KEYS, чтобы начать создание индексов, что может занять некоторое время, но не так долго, как делать это для каждой вставки.

5
ответ дан 24 November 2019 в 15:36
поделиться

Вы можете попробовать использовать объект DDBulkLoad.

// Get a DDBulkLoad object
DDBulkLoad bulkLoad = DDBulkLoadFactory.getInstance(connection);
bulkLoad.setTableName(“mytable”);
bulkLoad.load(“data.csv”);
1
ответ дан 24 November 2019 в 15:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: