Сохранение более 1000 записей в базу данных одновременно

StackOverflow https://stackoverflow.com/questions/982295

Вопрос

Сейчас я использую NHibernate.У меня есть ситуация, когда мне нужно сохранить кучу записей в базе данных следующим образом:

var relatedTopics = GetRelatedTopics(topic);
foreach (var relatedTopic in relatedTopics /* could be anywhere from 10 - 1000+ */)
{
    var newRelatedTopic = new RelatedTopic { RelatedTopicUrl = relatedTopic, TopicUrl = topic.Name };
    _repository.Save(newRelatedTopic);
}

Когда нужно сохранить массу записей, очевидно, что необходимость многократного обращения к базе данных очень утомительна.Какой подход лучше?Могу ли я сделать какое-то пакетное обновление?Лучше ли мне использовать DataSet?

Спасибо

Это было полезно?

Решение

установка adonet.batch_size может улучшить ситуацию.

Для этого вам придется

  • установите adonet.batch_size в конфигурации NH

Пример:

    m_sessionFactory = Fluently
         .Configure()
         .Database(MsSqlConfiguration
             .MsSql2005
             .ConnectionString(c => c.FromConnectionStringWithKey("testme"))
             )
         .Mappings(m => m.FluentMappings
             .AddFromAssemblyOf<TestImpl>())
         .ExposeConfiguration(config =>
         {
             config.SetProperty("adonet.batch_size", "1");
             m_configuration = config;
         })
         .BuildSessionFactory();
  • установите размер пакета в сеансе непосредственно перед сохранением

    using (ISession session = m_nhibernateSessionFactory.GetSession())
    using (var tx = session.BeginTransaction())
    {    
       session.SetBatchSize(1000);     
       foreach (var server in serverz)
       {
          session.SaveOrUpdate(server);
       }
       tx.Commit();
    }
    

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

Я считаю, что это то, что вы ищете:

Массовые операции с данными с помощью сессий без сохранения состояния NHibernate

По сути, вместо открытия ISession вы открываете IStatelessSession и в своем hibernate.cfg.xml вы можете установить:

 <property name="adonet.batch_size">100</property>

Я думаю, у вас есть несколько вариантов в зависимости от вашей ситуации.

Если вы можете использовать альфа-версии NHibernate 2.1, вы можете попробовать использовать новый доступный исполняемый файл HQL.

http://nhibernate.info/blog/2009/05/05/nh2-1-executable-hql.html

Ответ Тобиаса тоже подойдет.Простая установка размера пакета значительно повысит производительность.

Если вы хотите запачкать руки ADO.Net...

Выполнение массовой вставки на сервере Sql возможно с помощью массового копирования Sql.

Пример этого здесь: http://dotnetslackers.com/articles/ado_net/SqlBulkCopy_in_ADO_NET_2_0.aspx

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

Набор данных?Нет.Массовая вставка?Да.

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

Самый быстрый способ вставки записей — создать текстовый файл и использовать синтаксис ЗАГРУЗИТЬ ФАЙЛ.Большинство баз данных имеют удивительно быструю реализацию импорта файлов данных в базы данных.Для MySQL см. ниже:

http://dev.mysql.com/doc/refman/5.1/en/load-data.html

Информацию о других базах данных см. в соответствующем руководстве.Это полезно, если вы часто вставляете миллион или тысячи записей.В противном случае лучшее, что вы можете сделать, — это создать большой SQL с тысячами вставок и выполнить его напрямую при подключении к базе данных, пропуская ORM и связанные с ними проверки.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top