2013-07-26 3 views
0

Я использую Spring 2.5 и Hibernate, которые идут с ним. Я бегу против базы данных Oracle 11g.Каков наилучший способ написать загрузчик данных?

Я создал свои DAO, которые расширяют HibernateTemplate. Теперь я хочу написать загрузчика, который вставляет 5 миллионов строк в таблицу моих персонажей. Я написал это в простой форме, например, прочитал строку из файла CSV, превратил ее в человека, за исключением таблицы. Продолжайте делать это до тех пор, пока файл CSV не будет пустым.

Проблема в том, что я выхожу из кучного пространства около 450000 строк. Таким образом, я удваиваю размер памяти с 1024 м до 2048 м, и теперь у меня заканчивается память около 900000 строк.

Hmmmmm ....

Так что я прочитал кое-что о отключив кэш запросов для Hibernate, но я не использую кэш L2, так что я не думаю, что это вопрос.

Я читал некоторые вещи о дозировании JDBC2, но я не думаю, что это относится к спящему режиму.

Итак, мне интересно, может быть, есть что-то принципиальное в Hibernate, которого я пропускаю.

+1

Это буквально просто вопрос чтения из csv и загрузки в таблицу или вы делаете какую-то другую обработку? Если это первый, и это одноразовая статическая загрузка данных, я бы рекомендовал использовать загрузчик большого объема (например, Oracle sqlldr). – DaveRlz

+1

@DaveRlz Кроме загрузки двух таблиц, я не выполняю никакой другой обработки. Но я хочу, чтобы мое решение было независимым от базы данных. – Thom

+2

Если бы была только документация ... подождите, она есть: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#batch-inserts, http: //docs.jboss .org/hibernate/core/3.6/reference/en-US/html_single/# batch-statelesssession –

ответ

2

Если честно, я бы не использовал спящий режим для этого. ORM не предназначены для загрузки миллионов строк в БД. Не говоря, что вы не можете, но это немного похоже на рытье плавательного бассейна с электрическим сверлом; вы бы использовали для этого экскаватор, а не дрель.

В вашем случае я бы загрузил CSV непосредственно в БД с помощью приложения-загрузчика, которое поставляется с базами данных. Если вы не хотите этого делать, да, пакетные вставки будут более эффективными. Я не думаю, что Hibernate позволит вам сделать это легко, хотя. Если бы я был вами, я бы просто использовал простой JDBC или, самое большее, Spring JDBC.

Если у вас есть сложная бизнес-логика в сущности и абсолютно необходимо использовать Hibernate, вы можете очистить все N записей, как предлагает Ричард. Тем не менее, я бы подумал, что это довольно плохой взлом.

2

По моему опыту с EclipseLink, при открытии/обновлении одной транзакции при вставке/обновлении многие записи приводят к симптомам, которые вы испытали.

Вы работаете с EntityManager (что-то вроде JPA или Hybernate specific - он все еще управляет Entity s). Он пытается сохранить рабочий набор в памяти, для жизни транзакции.

Общее решение заключалось в том, чтобы совершить & перезапуск транзакции после каждых N вставок; типичный N для меня 1000.


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

0

Похоже, что у вас заканчивается пространство из-за вашего кеша первого уровня (сеанс Hibernate). Вы можете периодически очищать сеанс Hibernate, чтобы сохранить использование памяти. Но использование Hibernate для такой задачи загрузки будет медленным, потому что JDBC работает медленно. Если у вас есть хорошая идея, какова будет окружающая среда, у вас есть ограничение на количество данных, и у вас есть достаточно большое окно для обработки, тогда вы можете управлять, но в ситуации, когда вы хотите, чтобы он работал в нескольких на разных клиентских сайтах, и вы хотите свести к минимуму время, затрачиваемое на выяснение проблем из-за неработающего загрузочного задания какого-либо клиента, тогда вы должны пойти с инструментом массовой копии базы данных.Подход с массовым копированием означает, что база данных приостанавливает проверку ограничений и построение индекса и ведение журнала транзакций, вместо этого она концентрируется на том, чтобы как можно быстрее вырезать данные. Поскольку JDBC не получает такого уровня сотрудничества из базы данных, он не может конкурировать. На предыдущем задании мы заменили задачу загрузчика JDBC, которая заняла 8 часов для выполнения задачи SQLLoader, которая заняла 20 минут.

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

Смежные вопросы