Я использую NHibernate для ORM и консолидировал загрузку большого количества объектов в один большой запрос.
Я на самом деле загружаю словарь слова вокруг 500K записей, и каждое слово касается других. Выполнение процесса загрузки в фоновом режиме могло быть очень хитрым в нашем приложении, поскольку мы должны будем вручную загрузить запись, которая не была загружена вовремя, поскольку относительно любого слова можно было попросить в любое время. Наши единственные требования - то, что все данные загружаются максимально быстро. Я также попытался использовать сессию не сохраняющую состояние, но получил исключение, что сессии не сохраняющие состояние не могут выбрать наборы (по некоторым причинам, возможно, это имеет отношение к факту нет никакого кэша для сессий не сохраняющих состояние?)
Проблема состоит в том, что, хотя запрос занимает не больше, чем 25 секунд в SQLServer, требуется хорошо более чем 3 минуты для ICriteria. Список ().
Я использовал NHProf для профилирования процесса загрузки и нашел, что создание объектов является дорогостоящим делом, которое поднимает большую часть времени загрузки в NHibernate.
Есть ли что-нибудь, что я мог сделать для сокращения этой задержки? Действительно ли выделение памяти является дорогим, или действительно ли это - "заполнение" данных?
Спасибо!
Профилирование процесса создания (например, с анализатором Performance Performance) следует точно сказать, что является дорогостоящей операцией. Если вы уже играли с ленивой нагрузкой, то я думаю, что единственное хорошее решение заключается в том, чтобы инкапсулировать возвращенный список, чтобы включить пейджинг возврат меньших кусков в нескольких итерациях. Я не уверен, что Nibernate поддерживает ленивые списки результатов, как JPA, делает IPA (то есть не загрузки объектов от чтения данных до него).
Возможно, вам следует принять во внимание тот факт, что NHibernate (как и большинство ORM) не особенно подходит (или не предназначен) для этих типов сценариев массовой загрузки. Сколько строк вы пытаетесь загрузить, плюс-минус? Что ты пытаешься сделать? Предварительно заполнить кеш? Есть ли пакетная обработка?
Мне кажется, что вам следует серьезно обдумать цель своего приложения и соответствующим образом выбрать лежащие в основе технологии. Возможно, вы сможете пролить свет на свои намерения / требования?
ИЗМЕНИТЬ ОК, из ваших комментариев я понимаю, что вы здесь пытаетесь сделать. Первое, что я сделал бы, - это создал простой прототип с использованием необработанного ADO.NET для загрузки тех же данных, чтобы почувствовать максимальную производительность, достижимую при использовании стандартного доступа к данным и коллекций в памяти. Затем поиграйте с разными типами коллекций, чтобы увидеть, что хорошо работает при заполнении и поиске. Если загрузка таких данных по-прежнему слишком медленная, пора начать искать другие методы загрузки данных: файловые из локального файла данных, гидратация предварительно сериализованных объектов, некоторая форма быстрой загрузки по запросу и т. Д.
Загрузка 500 тыс. Объектов в сеанс NHibernate - не лучшая идея. Сессия должна быть недолгой и содержать относительно небольшое количество сущностей.
Если вы хотите выполнить такую пакетную обработку в NHibernate, вам следует взглянуть на StatelessSession вместо обычного сеанса. Использование сеанса без сохранения состояния, скорее всего, значительно повысит производительность в этом сценарии. Однако при использовании сеанса без сохранения состояния вы теряете преимущества кеша первого уровня NHibernate, такие как отслеживание изменений.
Дополнительную информацию о StatelessSession можно найти в этой статье и в документации NH на сайте nhibernate.info.
В этом случае я также рекомендовал бы вам рассмотреть возможность использования прямого ADO.NET вместо NHibernate. Я не говорю, что вы должны полностью переключить свою стратегию доступа к данным на ADO.NET, но вы можете рассмотреть возможность использования ADO.NET для пакетных операций и использования NHibernate для других случаев.