Советы по ускорению JDBC пишет? - PullRequest
14 голосов
/ 15 декабря 2008

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

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

Ответы [ 4 ]

8 голосов
/ 16 декабря 2008

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

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

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

  1. Драйвер JDBC, исправленный для поддержки COPY, такой как one .
  2. Если данные, которые вы вставляете, и база данных находятся на одном физическом компьютере, вы можете записать данные в файл в файловой системе, а затем использовать команду COPY для массового импорта данных.

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

3 голосов
/ 16 декабря 2008

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

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

1 голос
/ 15 декабря 2008

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

1 голос
/ 15 декабря 2008

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

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

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

Удачи!

...