2009-06-11 27 views
10

Tôi hiện đang sử dụng NHibernate. Tôi có một tình huống mà tôi cần phải lưu một loạt các hồ sơ để cơ sở dữ liệu như thế này:Tiết kiệm 1000+ bản ghi vào cơ sở dữ liệu tại một thời điểm

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

Khi có một tấn các hồ sơ lưu này rõ ràng là rất thuế phải nhấn cơ sở dữ liệu nhiều lần. Cách tiếp cận tốt hơn là gì? Có một số loại cập nhật hàng loạt mà tôi có thể làm không? Tôi có sử dụng DataSet tốt hơn không?

Cảm ơn

+0

Tôi sẽ chấp nhận câu trả lời của David P là giải pháp cho câu hỏi. –

Trả lời

12

cài đặt adonet.batch_size có thể cải thiện tình hình.

Cho rằng bạn phải

  • bộ adonet.batch_size trong cấu hình NH

Ví dụ:

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(); 
  • thiết lập kích thước hàng loạt trên phiên ngay trước tiết kiệm

    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

Bạn có thể xây dựng một chút không? – Micah

+1

Tại sao bạn đặt m_configuration? Tôi nhận được một lỗi vẫn còn trên SetBatchSize và tôi đã cố gắng tìm ra lý do tại sao. Tôi đang sử dụng Oracle, có lẽ đó không hỗ trợ kích thước hàng loạt ?? –

1

Số liệu? Số Chèn hàng loạt? Vâng.

Nếu bạn đang chèn nhiều bản ghi và chèn rất đơn giản, bạn nên xem xét thực hiện Chèn hàng loạt và kéo ORM.

+0

Bạn có thể giải thích thêm về điều đó không? Tôi chưa bao giờ xử lý với chèn số lượng lớn trước đây. Cảm ơn! – Micah

1

Cách nhanh nhất để chèn bản ghi là tạo tệp văn bản và sử dụng cú pháp LOAD FILE. Hầu hết các cơ sở dữ liệu có triển khai nhanh chóng đáng kể để nhập các tệp dữ liệu vào cơ sở dữ liệu. Đối với MySQL, xem bên dưới:

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

Để biết các cơ sở dữ liệu khác, hãy tham khảo hướng dẫn thích hợp. Điều này rất hữu ích nếu bạn đang chèn một triệu bản ghi hoặc hàng nghìn bản ghi thường xuyên. Nếu không, tốt nhất bạn có thể làm là tạo một SQL lớn với 1000 giây chèn và thực hiện điều đó trên kết nối cơ sở dữ liệu của bạn trực tiếp, bỏ qua các ORM và các xác thực liên quan của chúng.

3

Tôi nghĩ bạn có một số tùy chọn tùy thuộc vào tình huống của bạn.

Nếu bạn có thể sử dụng NHibernate 2.1 alphas, bạn có thể thử sử dụng HQL thực thi mới có sẵn.

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

Câu trả lời của Tobias cũng sẽ hoạt động. Chỉ cần thiết lập kích thước lô sẽ tăng hiệu suất một cách đáng kính.

Nếu bạn muốn bẩn tay với ADO.Net ...

Làm chèn số lượng lớn trong Sql Server có thể thông qua việc sử dụng Sql Bulk Copy.

Một ví dụ trong số đó là ở đây: http://dotnetslackers.com/articles/ado_net/SqlBulkCopy_in_ADO_NET_2_0.aspx

Đối với tôi nó có vẻ như bạn đang tạo ra một thực thể mới dựa tắt của một thực thể trong cơ sở dữ liệu.Với tôi, điều đó có vẻ giống như một kịch bản lý tưởng để sử dụng một thủ tục lưu sẵn.

4

Tôi tin rằng đây là những gì bạn đang tìm kiếm:

Bulk Data Operations With NHibernate's Stateless Sessions

Về cơ bản thay vì mở một ISession, bạn mở một IStatelessSession, và trong hibernate.cfg.xml của bạn, bạn có thể thiết lập:

<property name="adonet.batch_size">100</property> 
Các vấn đề liên quan