12

Đó là một vài ngày mà tôi đang làm việc để cải thiện hiệu suất Chèn NHibernate.Chèn phiên không trạng thái của NHibernate chậm

Tôi muốn đọc nhiều bài viết (như this one) mà stateless session có thể chèn như 1000 ~ 2000 hồ sơ mỗi giây .... Tuy nhiên, thời gian tốt nhất mà nó có thể chèn 1243 hồ sơ là hơn 9 giây cho tôi:

var sessionFactory = new NHibernateConfiguration().CreateSessionFactory(); 
using (IStatelessSession statelessSession = sessionFactory.OpenStatelessSession()) 
{ 
    statelessSession.SetBatchSize(adjustmentValues.Count); 

    foreach (var adj in adjustmentValues) 
     statelessSession.Insert(adj); 
} 

lớp:

public partial class AdjustmentValue : PersistentObject, IFinancialValue 
{ 
    public virtual double Amount { get; set; } 
    public virtual bool HasManualValue { get; set; } 
    public virtual bool HasScaleValue { get; set; } 
    public virtual string Formula { get; set; } 
    public virtual DateTime IssueDate { get; set; } 

    public virtual CompanyTopic CompanyTopic { get; set; } 
} 

Bản đồ các lớp:

public class AdjustmentValueMap : ClassMap<AdjustmentValue> 
{ 
    public AdjustmentValueMap() 
    { 
     Id(P => P.Id); 

     Map(p => p.Amount); 
     Map(p => p.IssueDate); 
     Map(p => p.HasManualValue); 
     Map(p => p.HasScaleValue); 
     Map(p => p.Formula); 

     References(p => p.CompanyTopic) 
      .Fetch.Join(); 
    } 
} 

Tôi có thiếu gì đó không? Bất kỳ ý tưởng nào để tăng tốc độ chèn?

enter image description here

Các truy vấn được tạo ra sẽ được giống như dưới đây:

enter image description here

Trả lời

17

từ giao diện kết quả NHProf bạn đang sử dụng danh tính làm POID của bạn. Do đó bạn không thể tận dụng lợi thế của việc viết theo đợt. mỗi chèn/cập nhật/xóa là một lệnh riêng biệt. đó là lý do tại sao nó mất quá nhiều thời gian.

nếu bạn thay đổi POID thành hilo, guid hoặc guid.comb và đặt kích thước lô thành 500 hoặc 1000 thì bạn sẽ thấy sự cải thiện mạnh mẽ trong thời gian ghi.

4

tôi giả sử bạn đang sử dụng SQL Server 2008.

vài điều mà tôi suy nghĩ. Bạn đang sử dụng khóa nhận dạng (chọn SCOPE_IDENTITY() trong đầu ra mẫu của bạn) làm khóa chính cho các thực thể của bạn? Nếu có thì tôi tin NHibernate phải thực hiện cuộc gọi SCOPE_IDENTITY() cho từng đối tượng trước khi đối tượng thực sự được lưu vào cơ sở dữ liệu. Vì vậy, nếu bạn đang chèn 1000 đối tượng Nhibernate sẽ tạo ra 1000 câu lệnh INSERT và 1000 chọn các câu lệnh SCOPE_IDENTITY().

Tôi không chắc chắn 100% nhưng nó cũng có thể phá vỡ quá trình trộn. Vì bạn đang sử dụng NHProf thì nó nói gì? Nó có cho thấy rằng tất cả các câu lệnh được nhóm lại với nhau hoặc bạn có thể chọn câu lệnh INSERT riêng lẻ trong giao diện người dùng NHProf không? Nếu chèn của bạn không được sắp xếp theo lô, bạn sẽ có thể thấy cảnh báo "Số lượng lớn từng người viết" trong NHProf.

Edit:

Nếu bạn không thể thay đổi thế hệ danh tính của bạn thì bạn có thể sử dụng SqlBulkCopy. Tôi đã sử dụng nó với NHibernate trong việc di chuyển dữ liệu và nó hoạt động. Ayende Rahien has sample on his blog giúp bạn bắt đầu.

+0

có, chèn là các truy vấn riêng biệt. –

+1

Đối với chèn số lượng lớn mà thời gian quan trọng thì tôi thực sự sẽ đi cho giải pháp 'SQLBulkCopy'. – Rippo

Các vấn đề liên quan