使用NHiberbnate、Oracle和Fluent NHibernate进行批量插入
编辑: 我正在使用Fluent NHibernate,NHibernate和Oracle数据库 因此,我正在进行的测试如下:使用NHiberbnate、Oracle和Fluent NHibernate进行批量插入,nhibernate,fluent-nhibernate,bulkinsert,Nhibernate,Fluent Nhibernate,Bulkinsert,编辑: 我正在使用Fluent NHibernate,NHibernate和Oracle数据库 因此,我正在进行的测试如下: [Test] public void CanIInsertLargeVolumesOfDataToOracleInUnder5Mins() { var stopwatch = new Stopwatch(); stopwatch.Start(); var entities = GetEntities(
[Test]
public void CanIInsertLargeVolumesOfDataToOracleInUnder5Mins()
{
var stopwatch = new Stopwatch();
stopwatch.Start();
var entities = GetEntities();
using (var session = UnitOfStatelessWork.GetUnderlyingSession())
{
using (var transaction = session.BeginTransaction(IsolationLevel.ReadCommitted))
{
foreach (var entity in entities.Select(entity => new EntityObject(entity) {SomeProperty = 19675464.25M}))
{
session.Insert(entity);
}
transaction.Commit();
}
}
stopwatch.Stop();
var time = stopwatch.Elapsed;
Assert.IsTrue(time < TimeSpan.FromMinutes(5.0));
}
那么对于Oracle:
var fluentConfiguration = Fluently
.Configure()
.Database(OracleClientConfiguration.Oracle10.AdoNetBatchSize(1000).ConnectionString(c => c.Is(connStr)))
.Mappings(m => m.FluentMappings.AddFromAssembly(mappingAssembly));
fluentConfiguration.ExposeConfiguration(f =>
{
f.SetProperty("generate_statistics", "false");
f.SetProperty("command_timeout", "60");
f.SetProperty("hibernate.connection.driver_class", "NHibernate.Driver.OracleDataClientDriver");
f.SetListener(ListenerType.PreInsert, new AuditEventListener());
f.SetListener(ListenerType.PreUpdate, new AuditEventListener());
f.SetProperty("hibernate.order_inserts", "true");
f.SetProperty("hibernate.order_updates", "true");
});
然后,我对这两个数据库使用无状态会话和批处理,可以在大约100秒内将750000条记录插入SQL DB
在Oracle中,同样的测试大约需要12分钟
有人看到我没有看到的任何空白错误吗?- 无状态会话不使用批处理
- 当您
SetProperty(“adonet.batch\u size”,“1”)时,您正在覆盖批大小
我的建议是使用.net探查器来确定时间花在哪里。谢谢您的回答。因此,我将把这归因于急切的编辑,我实际上删除了
SetProperty(“adonet.batch\u size”,“1”)
的行,在发布问题之后,现在从帖子中删除了。关于无状态会话和批处理,我曾与NHProf进行过分析,我确信批处理确实适用于无状态会话,但是,我可能错了,我当时在实验室,可以说是在很短的时间内,所以这可能是一个正常的会话。尽管如此,性能上的差异还是很明显,这里一定有什么问题?…顺便说一句,这是我急于编辑的,只是为了避免混淆!所以在Oracle中,NHibernate似乎不是快速插入数据的最佳选择。。。最终使用ODP.NET和数组绑定。。。在大约50秒内插入750000条记录。分类!
var fluentConfiguration = Fluently
.Configure()
.Database(MsSqlConfiguration.MsSql2005.ConnectionString(c => c.Is(connStr)))
.Mappings(m => m.FluentMappings.AddFromAssembly(mappingAssembly));
fluentConfiguration.ExposeConfiguration(f =>
{
f.SetProperty("generate_statistics", "false");
f.SetProperty("command_timeout", "60");
f.SetListener(ListenerType.PreInsert, new AuditEventListener());
f.SetListener(ListenerType.PreUpdate, new AuditEventListener());
f.SetProperty("adonet.batch_size", "1");
f.SetProperty("hibernate.order_inserts", "true");
f.SetProperty("hibernate.order_updates", "true");
});
var fluentConfiguration = Fluently
.Configure()
.Database(OracleClientConfiguration.Oracle10.AdoNetBatchSize(1000).ConnectionString(c => c.Is(connStr)))
.Mappings(m => m.FluentMappings.AddFromAssembly(mappingAssembly));
fluentConfiguration.ExposeConfiguration(f =>
{
f.SetProperty("generate_statistics", "false");
f.SetProperty("command_timeout", "60");
f.SetProperty("hibernate.connection.driver_class", "NHibernate.Driver.OracleDataClientDriver");
f.SetListener(ListenerType.PreInsert, new AuditEventListener());
f.SetListener(ListenerType.PreUpdate, new AuditEventListener());
f.SetProperty("hibernate.order_inserts", "true");
f.SetProperty("hibernate.order_updates", "true");
});