2012-09-06 54 views
2

我有NHibernate 3.3和Firebird 2.5.1的性能問題。我用ASP.NET MVC和本地(!)Firebird數據庫創建了一個非常簡單的例子。 但下面的代碼需要約1秒的執行時間?!?NHibernate和Firebird的性能問題

 var startTickCountWrite = Environment.TickCount; 

     IRepository<Project> repository = facade.ProjectRepository(null); 
     for (int i = 1; i <= 250; ++i) 
     { 
      var myProject = new Project { ProjectId = i }; 
      repository.Insert(myProject); 
     } 
     repository.Commit(); 

     var endTickCountWrite = Environment.TickCount; 

如果我把commit()放在for循環中大約需要5秒!

背後的倉庫和外觀沒什麼特別的。我只是將項目轉發到ISession.Insert。

項目只有ID和ProjectID作爲屬性。

任何人都可以告訴我什麼是錯的?

謝謝, 安德烈亞斯在1秒內

+2

因此,您在一秒內將250個插入到具有未知硬件/內存配置的開源數據庫中,並且您認爲這樣做很糟糕? –

+0

_When_你連接DBMS嗎?也許連接直到實際需要才建立,所以這1秒中的大部分時間可能會花在連接到DBMS上。至於Commit in循環,這是非常期望的 - 您正在支付耐用性價格。事務需要是ACID,但只有在事務結束時才需要執行「持久性」。因此,物理IO到磁盤可能會在明顯的SQL語句執行後推遲,並在您的事務正在處理其他語句時在後臺實際完成。如果您的交易過於細化,那麼您就擊敗了這一點。 –

回答

1

250對象不發聲驚人慢。爲了評估性能,提供一些比較也是很好的 - 直接針對Firebird執行相同數量的SQL需要多長時間?

NHibernate可以在某些情況下批量INSERT語句,但我不知道這是否適用於Firebird。 http://nhibernate.info/doc/nh/en/index.html#performance-batch-updates身份識別生成器的選擇也可以產生效果。一些生成器強制NHibernate立即執行INSERT語句,這將阻止使用批處理。從設計的角度來看,您可能需要更改一些內容: IRepository.Insert()通常被命名爲Add(),因爲它模仿集合接口(並且在集合上插入(如果存在的話),通常採用索引當然這裏沒有關係的參數)。此外,Commit()似乎不在存儲庫中,因爲您通常會涉及多個存儲庫實例,它們共享相同的事務和會話。

對於準確的時間測量,您可以使用System.Diagnostics的Stopwatch,因此您無需自行轉換該值。

+0

感謝您的回答。首先,我對250個插入片約1秒震驚。但有幾個其他的測試似乎沒問題。感謝您關於設計的提示。 – Andreas