Вставьте 50 тысяч записей в MySQL - PullRequest
0 голосов
/ 18 сентября 2009

Я хочу вставить 50 000 записей в MySQL через веб-сервис, написанный на Java, но вставляется только 20 000 записей.

Я не думаю, что в моем sql есть ограничение на размер (количество записей).

есть что-то, где я могу вставить / выбрать 50 тыс. Записей за один раз (навалом)

Ответы [ 8 ]

9 голосов
/ 18 сентября 2009

Разделите его на несколько транзакций, не вставляйте записи по 50 КБ подряд. Я думаю, что это проблема.

Редактировать: Поскольку это веб-сервис, возможно, во время передачи связь нарушена. Пожалуйста, убедитесь, что это не так =).

Ответ на комментарий ОП: Вместо

INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
... 49 990 INSERT later
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)

сделать

BEGIN TRANSACTION my_beloved_transaction
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
... 2k INSERT later
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
COMMIT TRANSACTION my_beloved_transaction

BEGIN TRANSACTION my_beloved_transaction
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
... 2k INSERT later
INSERT (......) INTO table (...)
INSERT (......) INTO table (...)
COMMIT TRANSACTION my_beloved_transaction

и т.д ...

2 голосов
/ 18 сентября 2009

Я не знаю, как вы делаете вставку, но вы можете просто просмотреть все, что вы хотите вставить, и, скажем, 5000 записей, вставить этот пакет с помощью веб-службы, а затем перейти к Следующая партия, пока вы не закончите. Таким образом, в этом примере вы будете делать 10 вызовов веб-службы, каждая из которых будет содержать 5000 записей.

Проверьте использование транзакций MySQL, чтобы вы могли остановить это, если с пакетом что-то пойдет не так (я сам не использовал их в MySQL, поэтому не могу помочь с этой частью).

1 голос
/ 18 сентября 2009

Может быть проблема с памятью? Попробуйте использовать PreparedStatement с командой addBatch () и выполняйте коммиты в пакетном режиме:

PreparedStatement stmt = prepareStatement(...);
int count = 0;
for (MyObject eachData : dataList) {
    stmt.setObject(1, eachData.getDate());
    stmt.setBigDecimal(2, eachData.getValue1());
    stmt.setBigDecimal(3, eachData.getValue2());
    stmt.addBatch();
    if (count++ > 100) {// flush the batch periodically, so batches don't get too large
        int[] ints = stmt.executeBatch();
        log.log(Level.INFO, "Inserted " + ints.length + " new records");
        stmt.clearBatch();
        count = 0;
    }
}
final int[] ints = stmt.executeBatch();
log.log(Level.INFO, "Inserted " + ints.length + " new records");
1 голос
/ 18 сентября 2009

Проверяете ли вы ошибки при сбое запроса. Возможно ли, что вы работаете с размером max_allowed_packet для вашего сервера? Я не уверен, что поведение с массовыми вставками, которые не в транзакциях, но это может вызвать необычные ошибки с большими операторами SQL:

http://dev.mysql.com/doc/refman/5.1/en/packet-too-large.html

1 голос
/ 18 сентября 2009

Если это не быстрое и грязное доказательство концепции, не должно иметь значения, что это веб-сервис. Веб-сервис - это просто внешний интерфейс.

Вы должны подходить к этому как к проблеме MySQL / JDBC. Если вам нужны все или не все вставки для успеха, вам нужна одна длительная транзакция, вероятно, с массовой вставкой.

Проблема веб-службы должна быть отдельной - вас вполне может беспокоить, может ли клиент дождаться завершения вставок для подтверждения синхронизации, или вам нужно перезвонить. Это проблема дизайна веб-сервиса. Разъедините и обработайте их по отдельности.

0 голосов
/ 19 сентября 2009

Когда вы запускаете транзакцию, данные должны сохранять сегмент отката только в случае сбоя транзакции. Диск и память связаны с этим журналом, поэтому должен быть установлен лимит. Я бы проверил значения по умолчанию и посмотрел, возможно, вы превысили один или оба.

Преимущество совершения небольших партий заключается в том, что сегмент отката каждый раз сбрасывается до нуля. Вот почему помогает разбить его на более мелкие партии.

0 голосов
/ 18 сентября 2009

вы можете использовать команду load infile mysql. сначала запишите все данные в один текстовый файл, затем загрузите в базу данных, используя команду load infile, для вставки большой записи потребуется очень мало времени и лучший способ.

0 голосов
/ 18 сентября 2009

Скорее всего, именно реализация процесса массовой / пакетной вставки / обновления вызывает ограничения. Если бы у вас было больше данных в каждой строке, то вы бы обнаружили, что они умирают с меньшим количеством вставляемых строк.

Попробуйте выполнить подмножество одновременно с несколькими пакетными / массовыми вставками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...