2012-03-30 29 views
13

Tôi muốn tăng tốc hoạt động số lượng lớn insert với NHibernate 3.2 trên Oracle 11g. Để làm điều này tôi đã cố gắngTăng tốc thao tác chèn hàng loạt với NHibernate

Session.Save(entity); 
Session.Flush(); 
Session.Clear(); 

... trong foreach vòng lặp của tôi, nhưng có một ngoại lệ gây ra bởi các đối tượng thiếu trong phiên:

thất bại trong việc uể oải khởi tạo một tập hợp các vai trò: MyClass.PropertyX, không có phiên hoặc phiên đã được đóng

nỗ lực khác là để thiết lập kích thước hàng loạt:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> 
    <session-factory> 
    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property> 
    <property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property> 
    <property name="connection.connection_string">xxx</property> 
    <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property> 
    <property name="adonet.batch_size">50</property> 
    <property name="query.substitutions">true=1, false=0</property> 
    <property name="proxyfactory.factory_class">NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate</property> 
    </session-factory> 
</hibernate-configuration> 

thêm tôi đặt Session.SetBatchSize(50) trong mã của tôi một có ngoại lệ sau đây:

Không kích thước hàng loạt được xác định cho các nhà máy phiên, trạm trộn là người tàn tật. Đặt adonet.batch_size = 1 để bật tính năng nhóm.

Vị trí duy nhất mà ngoại lệ này được ném là NonBatchingBatcher, vì vậy có vẻ như phiên của tôi có trình theo dõi sai.

Có gì sai ở đây? Làm thế nào tôi có thể tăng tốc độ chèn hàng loạt với NHibernate (không sử dụng các phiên statlese)?

+0

Trường hợp ngoại lệ đầu tiên của bạn là gì? Ngoài ra, nếu bạn thực hiện 'Flush' * bên trong vòng lặp *, bạn sẽ không được sắp xếp bất kỳ thứ gì. –

+0

@Diego Mijelshon đã thêm thông báo ngoại lệ – deamon

+0

@deamon là đa luồng này theo bất kỳ cách nào? – Newbie

Trả lời

1

Tại sao bạn xóa phiên?

Tôi nghĩ bạn không nên xóa phiên trong vòng lặp. Để đảm bảo rằng các thay đổi được ghi vào cơ sở dữ liệu tôi muốn sử dụng một giao dịch.

Mã giả:

foreach (var i in allElements) 
{ 
    using (var tx = session.BeginTransaction()) 
    { 
     ... do what you have to do with the object 
     tx.Commit(); 
    } 
} 

Đẩy nhanh tiến độ điều lên có những thứ khác có thể giúp - bạn phải xác định những gì bạn thực sự muốn làm trong vòng lặp.

35

Tiếp theo nên làm việc,

var testObjects = CreateTestObjects(500000); 

var stopwatch = new Stopwatch(); 
stopwatch.Start(); 
using (IStatelessSession session = sessionFactory.OpenStatelessSession()) 
using (ITransaction transaction = session.BeginTransaction()) 
{ 
    foreach (var testObject in testObjects) 
     session.Insert(testObject); 
    transaction.Commit(); 
} 

stopwatch.Stop(); 
var time = stopwatch.Elapsed; 

Ref: http://nhibernate.info/blog/2008/10/30/bulk-data-operations-with-nhibernate-s-stateless-sessions.html

+1

+1 Cách người ta nên trả lời! Đã lưu cho tôi thời gian – user919426

+0

Tôi có nên xóa bộ nhớ cache của mình sau khi sử dụng phiên không quốc tịch không? Hoặc các phiên có trạng thái có nhận các thay đổi được thực hiện bởi phiên không quốc tịch không? –

4

Tất cả các mẹo trên đều rất hợp lệ và rất hữu ích. Bạn muốn thêm một bộ sưu tập vào bộ sưu tập: tắt ghi nhật ký. Có SQL của bạn được hiển thị trong giao diện điều khiển làm chậm bạn đáng chú ý, cũng như hồ sơ bằng cách sử dụng NHProf, tự động bình luận và định dạng khá SQL đăng nhập thông qua NLog hoặc log4net. Trong trường hợp của chúng tôi:

cfg.AutoCommentSql = false; 
cfg.LogFormattedSql = false; 

giảm thời gian chèn hàng loạt của chúng tôi từ ~ 6 giây xuống chỉ hơn 1 giây. Vì vậy, trong khi đăng nhập có khả năng sẽ giúp bạn giải quyết các vấn đề nghiêm trọng hơn, nó đi kèm với một hit hiệu suất của riêng mình!

0

Tôi biết câu hỏi là về Oracle nhưng đối với máy chủ SQL tôi sẽ viết một thường trình để ánh xạ lớp và tạo ra một DataTable được SqlBulkInsert sử dụng, nhưng tôi phát hiện ra ai đó đã làm điều này.

https://kaylaniam.wordpress.com/2015/03/13/nhibernate-and-sqlbulkcopy/

Đây có lẽ là cách nhanh nhất để chèn số lượng lớn trên SQL Server.

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