Производительность вставки JDBC PostgreSQL - PullRequest
0 голосов
/ 25 мая 2018

Я испытываю прогрессивное замедление скорости вставки в базу данных PostgreSQL после первых нескольких тысяч вставок, и я не смог найти объяснения, почему это происходит.Возможно, кто-то может помочь объяснить это:

Проблема заключается в следующем:

Разобрать массив JSON в операторы вставки SQL, в две таблицы, связанные внешним ключом, все в одной транзакции, гдев случае ошибки откатывается только ошибочная запись (так что в подключенной таблице нет потерянных данных).

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

Таким образом, мое решение - начать транзакцию в начале файла и создать точку сохранения для каждой записи.Если с этой записью произошла ошибка, транзакция откатывается до этой точки сохранения (и точка сохранения освобождается), если ошибки нет, точка сохранения сбрасывается и импорт продолжается.

Теперь это работает достаточно хорошо,пока нет десятков или сотен тысяч записей для вставки.Первые несколько тысяч идут очень хорошо, вставляя между 300-400 в секунду, но затем начинают постепенно замедляться.

Done 200, rate 200/s, succeeded 200 failed 0
Done 300, rate 300/s, succeeded 300 failed 0
Done 400, rate 400/s, succeeded 400 failed 0
Done 500, rate 250/s, succeeded 500 failed 0
Done 600, rate 300/s, succeeded 599 failed 1
Done 700, rate 233/s, succeeded 699 failed 1
Done 800, rate 266/s, succeeded 799 failed 1
Done 900, rate 300/s, succeeded 899 failed 1
Done 1000, rate 250/s, succeeded 999 failed 1
Done 1100, rate 275/s, succeeded 1099 failed 1
...
Done 5200, rate 185/s, succeeded 5195 failed 5
Done 5300, rate 182/s, succeeded 5295 failed 5
Done 5400, rate 186/s, succeeded 5395 failed 5
Done 5500, rate 183/s, succeeded 5495 failed 5
...
Done 31000, rate 58/s, succeeded 30953 failed 47
Done 31100, rate 58/s, succeeded 31053 failed 47
Done 31200, rate 57/s, succeeded 31153 failed 47

Таким образом, после 30 000 вставок он замедлился до 1/5 от того, что он делал при запуске.Таблицы - это очень простые таблицы с несколькими VARCHAR, несколькими числами, первичным ключом и внешним ключом.Здесь нет функций, триггеров или чего-то еще.

Мне интересно, есть ли в JDBC что-то, что удерживает ресурсы, которые больше не нужны, что может быть причиной проблемы.Конечно, если он начинается с 300 / сек, то код, сеть и сервер БД способны поддерживать хотя бы это.

Я знаю, что пакетная обработка значительно улучшит его, но для описанного здесь варианта использования это не сработает.

1 Ответ

0 голосов
/ 12 июля 2018

Даже если вы «освободите точку сохранения», база данных сохраняет структуры памяти до конца транзакции .Вы действительно фиксируете строки?

  1. Возможно, вы захотите использовать пакетный API и использовать точки сохранения перед пакетными инструкциями.Например: используйте пакет из 100, и если это не удастся, вы можете повторить попытку один за другим.Или повторите попытку с партией 50. Это включает пакетный API, уменьшает количество требуемых точек сохранения, позволяет пропускать недопустимые строки и т. Д. И т. Д.
  2. Вы можете время от времени фиксировать транзакцию, чтобы избежать высокого потребления памяти.на бэкэнд-стороне.

Если вышеприведенное не помогает, тогда продолжайте и профилируйте процесс базы данных (например, через perf), чтобы увидеть, что вызывает узкое место.

...