为什么SQLite插入会很慢?(交易)

本文关键字:交易 SQLite 插入 为什么 | 更新日期: 2023-09-27 18:16:42

我在SQLite数据库中插入8500行。它需要> 30sec在Core 2双核上。在此期间,它使用了70%的CPU,那么问题是CPU使用率。

我正在使用transaction.

我在一个临时文件中动态创建数据库、表和插入。那么我就不需要担心腐败等问题了。

我只是试着使用这个,但是没有帮助:

PRAGMA journal_mode = OFF;
PRAGMA synchronous = OFF;

我还能做什么?

如果我在Firefox SQLite管理器插件中运行相同的脚本,它会立即运行。

运行分析器。

所有的时间都在

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

为什么SQLite插入会很慢?(交易)

我不知道为什么pst删除了他的答案,所以我将重新发布相同的信息,因为这似乎是正确的答案。

根据SQLite常见问题解答- INSERT真的很慢-我每秒只能做几十次INSERT

实际上,在一台普通的台式计算机上,SQLite每秒可以轻松地执行50,000条或更多的INSERT语句。但是它每秒只能处理几十个事务

默认情况下,每个INSERT语句都是自己的事务。但是如果用BEGIN包围多个INSERT语句…COMMIT,然后将所有插入分组到单个事务中。

所以基本上你需要将insert分组到更少的事务中。

Update:所以问题可能主要是由于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();
        }
    }
}

是否尝试过参数化插入?根据我的经验,事务处理可以大大提高速度,但参数化查询的影响更大。