2011-12-01 32 views
1

我在SQLite數據庫插入8500行。 Core 2 Duo需要> 30sec。 在這段時間內它使用70%的CPU,那麼問題在於CPU使用率。爲什麼SQLite插入會很慢? (事務使用)

我正在使用交易。

我創建數據庫,表和插入在一個臨時文件上的動態。然後,我不需要擔心腐敗等

我只是試圖利用這一點,但不要幫助:

PRAGMA journal_mode = OFF; 
PRAGMA synchronous = OFF; 

更重要的是我可以做什麼?

如果我在Firefox SQLite Manager插件上運行相同的腳本,它會立即運行。

我運行了剖析器。

所有的時間都在

27seg System.Data.SQLite.SQLite3.Prepare(SQLiteConnection, String, SQLiteStatement, UInt32, String&) 

此方法調用三種方法

12seg System.Data.SQLite.SQLiteConvert.UTF8ToString(IntPtr, Int32) 
9seg System.Data.SQLite.SQLiteConvert.ToUTF8(String) 
4seg System.Data.SQLite.UnsafeNativeMethods.sqlite3_prepare_interop(IntPtr, IntPtr, Int32, IntPtr&, IntPtr&, Int32&) 

您出示插入。這裏:

INSERT INTO [Criterio] ([cd1],[cd2],[cd3],[dc4],[dc5],[dt6],[dc7],[dt8],[dt9],[dt10],[dt11])VALUES('FFFFFFFF-FFFF-FFFF-FFFF-B897A4DE6949',10,20,'',NULL,NULL,'',NULL,julianday('2011-11-25 17:00:00'),NULL,NULL); 

表:

CREATE TABLE Criterio (
    cd1   integer NOT NULL, 
    cd2   text NOT NULL, 
    dc3  text NOT NULL, 
    cd4 integer NOT NULL, 
    dt5   DATE NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    dt6   DATE NULL, 
    dt7   DATE NULL, 
    dc8 TEXT NULL, 
    dt9 datetime NULL, 
    dc10   TEXT NULL, 
    dt11   datetime NULL, 
    PRIMARY KEY (cd2 ASC, cd1 ASC) 

);

C#代碼:

 scriptSql = System.IO.File.ReadAllText(@"C:\Users\Me\Desktop\ScriptToTest.txt"); 

     using (DbCommand comando = Banco.GetSqlStringCommand(scriptSql)) 
     { 
      try 
      { 
       using (TransactionScope transacao = new TransactionScope()) 
       { 
        Banco.ExecuteNonQuery(comando); 
        transacao.Complete(); 
       } 
      } 
      catch (Exception ex) 
      { 
       Logging.ErroBanco(comando, ex); 
       throw; 
      } 
     } 
+0

您確定*正在使用單筆交易嗎? – 2011-12-01 10:39:02

+0

是的,我確定。我嘗試使用(TransactionScope transacao = new TransactionScope())和命令文本中的BEGIN TRANSACTION ... COMMIT。 –

+1

我不知道這是否是相關的,但檢查您的防病毒軟件,否則你可以使用Process Explorer的知道是否有出頭你的數據庫文件的寄生蟲程序 –

回答

3

我不知道爲什麼PST刪掉了他的答案,所以我會從它重新發布相同的信息,這似乎是正確的答案。

據SQLite的常見問題 - INSERT is really slow - I can only do few dozen INSERTs per second

實際上,SQLite的將很容易做到的平均桌面計算機上每秒5萬個以上的INSERT語句。但它只會做幾十個交易每秒

...

默認情況下,每一個INSERT語句是它自己的事務。但是,如果使用BEGIN ... COMMIT包圍多個INSERT語句,則所有插入將分組爲單個事務。

因此,基本上你需要將INSERT分組爲少量事務。

更新:那麼問題可能主要是由於SQL腳本的龐大規模 - SQLite的需要分析整個腳本纔可以執行,但解析器將被設計來解析小腳本不是大規模的!這就是爲什麼你看到這麼多時間花在SQLite3.Prepare方法上的原因。

相反,你應該在你的C#代碼的循環使用參數化查詢和插入記錄,例如,如果你的數據是CSV格式的文本文件,你可以使用這樣的事情:

using (TransactionScope txn = new TransactionScope()) 
{ 
    using (DbCommand cmd = Banco.GetSqlStringCommand(sql)) 
    { 
     string line = null; 
     while ((line = reader.ReadLine()) != null) 
     { 
      // Set the parameters for the command at this point based on the current line 
      Banco.ExecuteNonQuery(cmd); 
      txn.Complete(); 
     } 
    } 
} 
+0

交易 –

+0

@Fujiy從你的代碼似乎每個INSERT是在自己的事務裏面它已經但是,除非'scriptSql'包含許多插入語句,否則目標是讓所有INSERT在**相同**事務中執行。 – Justin

+0

是,scriptSql有4K插入 –

0

有你試過一個參數化插入?根據我的經驗,事務處理會提高速度,但參數化查詢會產生更大的影響。

+0

我需要重構許多代碼。我從sql服務器中選擇生成插入。問題是,在Firefox中,它只用了1次 –