为什么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;
}
}
我不知道为什么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();
}
}
}
是否尝试过参数化插入?根据我的经验,事务处理可以大大提高速度,但参数化查询的影响更大。