Более быстрый способ пакетного сохранения с Hibernate? - PullRequest
3 голосов
/ 12 августа 2010

У меня есть программа, которая читает построчный текстовый файл, создает объект-сущность Hibernate из каждой строки и сохраняет их. У меня есть несколько таких текстовых файлов для обработки, каждый из которых имеет около 300 000 строк. Я обнаружил, что моя текущая реализация мучительно медленная, и мне интересно, могу ли я что-то сделать, чтобы улучшить ситуацию.

Мой основной метод обрабатывает текстовый файл построчно, например:

// read the file line by line
FileInputStream fileInputStream = new FileInputStream(new File(fileName));
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
int lineCount = 0;
String line = bufferedReader.readLine();
while (line != null)
{
    // convert the line into an Observations object and persist it
    convertAndPersistObservationsLine(line);

    // if the number of lines we've processed has built up to the JDBC batch size then flush
    // and clear the session in order to control the size of Hibernate's first level cache
    lineCount++;
    if (lineCount % JDBC_CACHE_SIZE == 0)
    {
        observationsDao.flush();
        observationsDao.clear();
    }

    line = bufferedReader.readLine();
}

Метод convertAndPersistObservationsLine () просто разбивает текстовую строку на токены, создает новый объект сущности, заполняет поля сущности данными из токенов, а затем сохраняет объект с помощью DAO, которая вызывает метод Session.saveOrUpdate () Hibernate. Методы DAO flush () и clear () являются прямыми вызовами соответствующих методов Hibernate Session.

Для свойства Hibernate 'hibernate.use_second_level_cache' установлено значение false, а для свойства Hibernate 'hibernate.jdbc.batch_size' установлено значение 50, как и для константы Java JDBC_CACHE_SIZE.

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

Заранее спасибо за помощь.

- Джеймс

Ответы [ 3 ]

8 голосов
/ 13 августа 2010

Сам код и конфигурация Hibernate выглядят правильно (под правильным я имею в виду, что они следуют идиоме пакетной вставки из документации).Но вот некоторые дополнительные предложения:

Как уже упоминалось, убедитесь, что абсолютно , что вы не используете генератор идентификаторов, который побеждает пакетирование, как IDENTITY.При использовании GenerationType.AUTO поставщик сохраняемости выберет подходящую стратегию в зависимости от базы данных, поэтому, в зависимости от вашей базы данных, вам может потребоваться изменить ее для стратегии TABLE или SEQUENCE (поскольку Hibernateможет кэшировать идентификаторы, используя алгоритм hi-lo).

Также убедитесь, что Hibernate пакетируется, как и ожидалось.Для этого включите ведение журнала и следите за BatchingBatcher, чтобы отследить размер выполняемого пакета (будет записан в журнал).

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

3 голосов
/ 12 августа 2010

Несколько вещей:

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

  2. Как вы подключаетесь к базе данных?Все ли это происходит в одной транзакции с повторным использованием одного и того же соединения?

  3. Вы случайно не используете идентификатор identity?В документации говорится, что пакетирование JDBC отключается автоматически, если вы :

Hibernate прозрачно отключает пакетную вставку на уровне JDBC, если вы используете генератор идентификаторов идентификаторов.

1 голос
/ 25 октября 2010

Если вы используете MySQL, вы можете захотеть включить rewriteBatchedStatements , поскольку MySQL не поддерживает пакетную форму привязок параметров оператора подготовки.Он запишет ваши операторы вставки в форму как «INSERT INTO YourEntity VALUES (...), (...), (...)».

Пожалуйста, обратитесь к: http://shengchien.blogspot.com/2010/10/hibernate-batch-processing-with-mysql.html

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