2009-06-11 19 views
10

Używam obecnie NHibernate. Mam sytuacji, gdy trzeba zapisać kilka rekordów do bazy danych tak:Zapisywanie ponad 1000 rekordów do bazy danych w czasie

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); 
} 

Gdy istnieje mnóstwo rekordów, aby zapisać to oczywiście bardzo opodatkowania mający trafić, że wiele razy bazy danych. Jakie jest lepsze podejście? Czy mogę zrobić jakąś aktualizację zbiorczą? Czy lepiej skorzystać z DataSet?

Dzięki

+0

Chciałbym przyjąć odpowiedź Davida P jako rozwiązanie tego pytania. –

Odpowiedz

12

ustawienie adonet.batch_size mogłyby poprawić sytuację.

Do tego trzeba

  • ustawionej adonet.batch_size w konfiguracji NH

Przykład:

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(); 
  • ustawić wielkość wsadu na sesji tuż przed zapisz

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

Czy możesz trochę rozwinąć? – Micah

+1

Dlaczego ustawiasz m_configuration? Wystąpił błąd nadal w SetBatchSize i próbowałem dowiedzieć się, dlaczego. Używam Oracle, może to nie obsługuje rozmiaru partii? –

1

Zestaw danych? Wstawianie luzem? Tak.

Jeśli wstawiasz wiele rekordów, a wstawki są dość uproszczone, powinieneś spojrzeć na tworzenie insertów zbiorczych i wyciąganie ORM.

+0

Czy możesz opracować więcej? Nigdy wcześniej nie zajmowałem się insertami zbiorczymi. Dzięki! – Micah

1

Najszybszym sposobem na wstawienie rekordów jest wygenerowanie pliku tekstowego i użycie składni LOAD FILE. Większość baz danych ma niezwykle szybkie implementacje do importowania plików danych do baz danych. MySQL, patrz poniżej:

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

dla innych baz danych znajdują się w odpowiedniej instrukcji obsługi. Jest to przydatne, jeśli często wstawiasz milion rekordów lub tysiące rekordów. W przeciwnym razie najlepiej jest utworzyć duży SQL z tysiącami wstawień i wykonać to bezpośrednio na połączeniu z bazą danych, pomijając procedury ORM i powiązane z nimi sprawdzania poprawności.

3

Myślę, że masz wiele opcji w zależności od sytuacji.

Jeśli możesz użyć NHibernate 2.1 alphphas, możesz spróbować użyć nowego dostępnego HQL Executable.

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

odpowiedź Tobias będzie działać jak również. Samo ustawienie wielkości partii poprawi wydajność.

Jeśli chcesz brudne ręce z ADO.Net ...

Doing Duże wkładki w SQL Server jest możliwa dzięki wykorzystaniu SQL luzem Copy.

Przykładem tego jest tutaj: http://dotnetslackers.com/articles/ado_net/SqlBulkCopy_in_ADO_NET_2_0.aspx

Dla mnie wydaje się, że podczas tworzenia nowego podmiotu w oparciu off innego podmiotu w bazie danych.Dla mnie wydaje się idealny scenariusz do korzystania z procedury przechowywanej.

Powiązane problemy