Советы по ускорению записи JDBC?

Я пишу программу, которая выполняет много операций записи в базу данных Postgres. В типичном сценарии я бы написал, скажем, 100 000 строк в хорошо нормализованной таблице (три внешних целочисленных ключа, комбинация которых является первичным ключом и индексом таблицы). Я использую PreparedStatements и executeBatch (), но мне удается только вставить, скажем, 100 тыс. Строк примерно за 70 секунд на моем ноутбуке, когда встроенная база данных, которую мы заменяем (которая имеет те же ограничения внешнего ключа и индексы), делает это в 10.

Я новичок в JDBC и не ожидаю, что он превзойдет пользовательскую встроенную БД, но я надеялся, что он будет всего в 2-3 раза медленнее, а не в 7 раз. Что-нибудь очевидное, чего я, возможно, не хватает? имеет значение порядок записи? (т.е. скажите, если это не порядок индекса?). На что посмотреть, чтобы выжать немного больше скорости?

Обновление: мне следовало добавить, что все вышеперечисленные обновления были выполнены за одну транзакцию, и что я попытался отбросить индексы без особого влияния (возможно, улучшение в лучшем случае на 20%, без учета повторного добавления индексов ).

Max Maximus 15.12.2008 21:03

Какой встроенной базой данных вы ее заменяете?

mainstringargs 15.12.2008 23:36
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
14
2
2 973
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

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

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

Удачи !

попробуйте отключить индексы и снова включить их после вставки. также оберните весь процесс в транзакцию

Ответ принят как подходящий

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

Итак, вот несколько решений, которые мы придумали:

Во-первых, все решения включают использование postgres Команда КОПИРОВАТЬ. Использование COPY для импорта данных в postgres на сегодняшний день является самым быстрым доступным методом. Однако драйвер JDBC по умолчанию в настоящее время не поддерживает КОПИРОВАНИЕ через сетевой сокет. Итак, если вы хотите использовать его, вам нужно будет использовать один из двух обходных путей:

  1. Драйвер JDBC исправлен для поддержки КОПИРОВАНИЯ, например, этот один.
  2. Если данные, которые вы вставляете, и база данных находятся на одном физическом компьютере, вы можете записать данные в файл в файловой системе, а затем использовать команду COPY для массового импорта данных.

Другие варианты увеличения скорости - использование JNI для доступа к postgres api, чтобы вы могли разговаривать через сокет unix, удаляя индексы и pg_bulkload проект. Однако, в конце концов, если вы не реализуете COPY, производительность всегда будет разочаровывать.

Спасибо за советы; Под «использованием JNI» вы имеете в виду использование JNI для доступа к COPY или для выполнения обычных команд SQL? т.е. вы ожидаете, что JNI-> C-> SQL будет быстрее, чем JDBC для того же количества INSERT?

Max Maximus 16.12.2008 10:44

Я не тестировал его в postgres, но считаю, что это стратегия, которую использует драйвер oracle. При прохождении через tcp по сравнению с сокетом unix возникают накладные расходы на производительность. В конце концов, индивидуальное решение для повышения производительности может не стоить затраченных усилий, поэтому я смотрю на него как на последнее средство.

Elijah 16.12.2008 14:56

Проверьте, настроено ли ваше соединение на autoCommit. Если autoCommit имеет значение true, то, если у вас есть 100 элементов в пакете, когда вы вызываете executeBatch, он выполнит 100 отдельных коммитов. Это может быть намного медленнее, чем вызов метода ExecutionBatch (), за которым следует один явный commit ().

Я бы избежал соблазна отбросить индексы или внешние ключи во время вставки. Он переводит таблицу в непригодное для использования состояние во время выполнения вашей нагрузки, поскольку никто не может запросить таблицу, пока индексы отсутствуют. Кроме того, это кажется достаточно безобидным, но что вы делаете, когда пытаетесь повторно включить ограничение, и оно терпит неудачу, потому что произошло то, чего вы не ожидали? У РСУБД есть ограничения целостности по какой-то причине, и отключение их даже «на некоторое время» опасно.

Другие вопросы по теме