Ver*_*ion 55 c# sqlite system.data.sqlite
我最近读到了关于SQLite的内容,并认为我会尝试一下.当我插入一条记录时,它表现良好.但是当我插入一百个它需要五秒钟时,随着记录计数的增加,时间也会增加.可能有什么不对?我正在使用SQLite Wrapper (system.data.SQlite):
dbcon = new SQLiteConnection(connectionString);
dbcon.Open();
//---INSIDE LOOP
SQLiteCommand sqlComm = new SQLiteCommand(sqlQuery, dbcon);
nRowUpdatedCount = sqlComm.ExecuteNonQuery();
//---END LOOP
dbcon.close();
Run Code Online (Sandbox Code Playgroud)
tid*_*all 76
围绕批量插入包装BEGIN\ END语句.Sqlite针对事务进行了优化.
dbcon = new SQLiteConnection(connectionString);
dbcon.Open();
SQLiteCommand sqlComm;
sqlComm = new SQLiteCommand("begin", dbcon);
sqlComm.ExecuteNonQuery();
//---INSIDE LOOP
sqlComm = new SQLiteCommand(sqlQuery, dbcon);
nRowUpdatedCount = sqlComm.ExecuteNonQuery();
//---END LOOP
sqlComm = new SQLiteCommand("end", dbcon);
sqlComm.ExecuteNonQuery();
dbcon.close();
Run Code Online (Sandbox Code Playgroud)
dav*_*d_p 32
我到处都读到创建事务是缓慢SQLite写入的解决方案,但重写代码并将所有SQLite写入包装在事务中可能会很长很痛苦.
我找到了一个更简单,安全且非常有效的方法:我启用了一个(默认情况下禁用)SQLite 3.7.0优化:Write-Ahead-Log(WAL).文档说它适用于所有unix(即Linux和OSX)和Windows系统.
怎么样 ?只需在初始化SQLite连接后运行以下命令:
PRAGMA journal_mode = WAL
PRAGMA synchronous = NORMAL
Run Code Online (Sandbox Code Playgroud)
我的代码现在运行速度快〜600%:我的测试套件现在运行38秒而不是4分钟:)
Jar*_*ley 31
尝试将所有插入(也称为批量插入)包装到单个事务中:
string insertString = "INSERT INTO [TableName] ([ColumnName]) Values (@value)";
SQLiteCommand command = new SQLiteCommand();
command.Parameters.AddWithValue("@value", value);
command.CommandText = insertString;
command.Connection = dbConnection;
SQLiteTransaction transaction = dbConnection.BeginTransaction();
try
{
//---INSIDE LOOP
SQLiteCommand sqlComm = new SQLiteCommand(sqlQuery, dbcon);
nRowUpdatedCount = sqlComm.ExecuteNonQuery();
//---END LOOP
transaction.Commit();
return true;
}
catch (SQLiteException ex)
{
transaction.Rollback();
}
Run Code Online (Sandbox Code Playgroud)
默认情况下,SQLite会包装事务中的每个插入,这会降低进程的速度:
INSERT非常慢 - 我每秒只能执行几十次INSERT
实际上,SQLite很容易在普通的台式计算机上每秒执行50,000或更多INSERT语句.但它每秒只会进行几十次交易.
事务速度受磁盘驱动器速度的限制,因为(默认情况下)SQLite实际上等待,直到事务完成之前数据确实安全地存储在磁盘表面上.这样,如果您突然断电或者操作系统崩溃,您的数据仍然是安全的.有关详细信息,请阅读SQLite中的原子提交.
默认情况下,每个INSERT语句都是自己的事务.但是如果用BEGIN ... COMMIT包围多个INSERT语句,则所有插入都被分组到一个事务中.提交事务所需的时间在所有随附的insert语句中分摊,因此每个insert语句的时间大大减少.
小智 8
请参阅ADO.NET帮助文件SQLite.NET.chm中的"优化SQL查询".该页面的代码:
using (SQLiteTransaction mytransaction = myconnection.BeginTransaction())
{
using (SQLiteCommand mycommand = new SQLiteCommand(myconnection))
{
SQLiteParameter myparam = new SQLiteParameter();
int n;
mycommand.CommandText = "INSERT INTO [MyTable] ([MyId]) VALUES(?)";
mycommand.Parameters.Add(myparam);
for (n = 0; n < 100000; n ++)
{
myparam.Value = n + 1;
mycommand.ExecuteNonQuery();
}
}
mytransaction.Commit();
}
Run Code Online (Sandbox Code Playgroud)