2010-12-17 97 views
0

我使用NHibernate 3與SQLite 3(更精確 - SQLCipher,但它在這種情況下沒有意義)。NHibernate與SQLite插入性能問題

我已經配置NHibernate的那樣:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" > 
    <session-factory> 
     <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property> 
     <property name="connection.driver_class">Test.NHibernate.MySqliteDriver, nhibernate_test</property>  
     <property name="connection.connection_string">Data Source=embedded</property> 
     <property name="dialect">NHibernate.Dialect.SQLiteDialect</property> 
     <property name="query.substitutions">true=1;false=0</property> 
     <property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu, Version=3.0.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4</property> 
     <property name="show_sql">true</property> 
    </session-factory> 
</hibernate-configuration> 

這裏,Test.NHibernate.MySqliteDriver, nhibernate_test是可以處理的連接字符串像Data Source=embedded自定義驅動程序。它不會執行任何特定的操作,除了創建SQLiteConnection到內存DataSource並使用ATTACH指令將一個數據庫附加到它。這也沒有意義。

我有一個表:

public class Product 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual string Category { get; set; } 
    public virtual bool Discontinued { get; set; } 
} 

映射到:

CREATE TABLE Prosucts (
    Id INTEGER PRIMARY KEY, 
    Name VARCHAR(250), 
    Category VARCHAR(250), 
    Discontinued INTEGER 
); 

隨着映射:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
        assembly="nhibernate_test" 
        namespace="Test.NHibernate.Domain"> 
    <class name="Product" table="Products"> 
     <id name="Id"> 
      <generator class="native" /> 
     </id> 
     <property name="Name" /> 
      <property name="Category" /> 
      <property name="Discontinued" /> 
    </class> 
</hibernate-mapping> 

在碼i執行以下操作:

var configuration = new Configuration(); 
configuration.Configure(typeof(Program).Assembly, "hibernate.cfg.xml");   
configuration.AddAssembly(typeof(Program).Assembly); 

var sessionFactory = configuration.BuildSessionFactory(); 

var product = new Product 
{ 
    Name = "Product", 
    Category = "Products", 
    Discontinued = true 
}; 

var product2 = new Product 
{ 
    Name = "Product 12", 
    Category = "Bad products", 
    Discontinued = true 
}; 

using (var session = sessionFactory.OpenSession()) 
{    
    using(var transaction = session.BeginTransaction()) 
    { 
     var sw = new Stopwatch(); 
     sw.Start();   

     session.Save(product); 
     Console.WriteLine("saved 1st in {0}", sw.Elapsed); 
     sw.Reset(); 
     sw.Start(); 

     session.Save(product2); 
     Console.WriteLine("saved 2nd in {0}", sw.Elapsed); 
     sw.Stop(); 

     transaction.Commit(); 
    } 
} 

並獲得disapointing輸出:

NHibernate的:INSERT INTO產品 (名稱,類別,已停產)VALUES(@ P0,P1 @,@ P2); select last_insert_rowid(); @ P0 = '產品'[類型:String(0)],@ P1 = '產品'[類型:String(0)],@ P2 =真[類型:布爾(0)]

保存第一在00:00:01.3444869

NHibernate:INSERT INTO Products(Name,Category,Discontinued)VALUES(@ p0,@ p1,@ p2); select last_insert_rowid(); @ P0 = '產品'[類型:String(0)],@ P1 = '產品'[類型:String(0)],@ P2 =真[類型:布爾(0)]

保存第二在00:00:00.0044215

那麼爲什麼插入第一條記錄需要這麼久??? (1.3秒),

回答

2

我看到了兩個可能的來源:

  1. 初始化會話緩存(S),當你給它的第一個實體進行跟蹤,並
  2. 的SQLite發射了它的內部生成第一個本地身份值
+1

它只是從睡眠中醒來,然後運行。嘗試第三和第四等,如果滯後只是第一個記錄,那麼這是正常的,沒有什麼可擔心的。 – Pradeep 2010-12-17 18:15:35

+0

是的,這總是隻有第一個記錄。順便說一句,我的進一步探索表明,它與NHibernate沒有任何關係。與Linq2Sql - 同樣的問題。所以這是SQLite的問題。但是......是一種限制還是有解決方法? – ILya 2011-01-17 05:37:10