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

В настоящее время я использую 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?

Спасибо

Ответ 1

настройка 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();
    }
    

Ответ 3

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

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

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

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

Если вы хотите загрязнить свои руки с помощью ADO.Net...

Выполнение массовых вложений на сервере Sql возможно с помощью Sql Bulk Copy.

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

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

Ответ 4

DataSet? Нет. Массовая вставка? Да.

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

Ответ 5

Самый быстрый способ вставить записи - это сгенерировать текстовый файл и использовать синтаксис LOAD FILE. Большинство баз данных имеют чрезвычайно быструю реализацию для импорта файлов данных в базы данных. Для MySQL см. Ниже:

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

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