2011-12-01 91 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次 –