2012-06-15 49 views
0

編輯:批量插入與NHiberbnate,Oracle和功能NHibernate

我使用功能NHibernate,NHibernate的與Oracle數據庫 所以我進行測試如下:

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

我連接字符串如下所示:

<connectionStrings> 
    <add connectionString="Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=myhost)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=some.service.com)));User ID=user;Password=user" name="OracleConnection" providerName="Oracle.DataAccess.Client" /> 
</connectionStrings> 

我有以下流利的配置,對於SQL Server:

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

我然後使用無狀態會話和配料的兩個數據庫,並且可以在大約插入75萬條記錄到SQL數據庫。 100秒。

在Oracle中,同樣的測試需要大約12分鐘。

任何人都可以看到我沒有看到的任何漏洞錯誤?

+0

因此,它看起來像NHibernate是不是在Oracle中的快速數據插入...結束使用ODP.NET和數組綁定... 750000記錄插入約。 50秒。排序! –

回答

0
  • 無狀態會話不使用批量
  • 你將覆蓋批量大小,當你SetProperty("adonet.batch_size", "1")

所以配料無關吧。我們沒有足夠的有關您的代碼如何執行插入以幫助您進一步的信息。

我的建議是,您使用.net分析器來確定時間花在哪裏。

+0

感謝您的回答。所以我會把它放在急切的編輯中,在發佈問題後,我實際上已將該行刪除到了'SetProperty(「adonet.batch_size」,「1」)',現在已從帖子中刪除。關於無狀態會話和批處理,我正在使用NHProf進行分析,我確信批處理對無狀態會話有效,但是,我可能是錯的,我在實驗室可以在小時間內發言,所以它可能已經正常會話。性能差異仍然很重要,這裏一定有什麼問題嗎? –

+0

......這是我急切的編輯方式,只是爲了避免混淆! –