C#:SQLiteDataAdapter INSERT 很慢
C#: SQLiteDataAdapter INSERT is Slow
我有一个 JSON 文件,其中包含 ~25-30K 个项目,我想将其保存在 sqlite 数据库中。
然而,SQLiteDataAdapter class 使用包含所有项目的 DataTable 对象更新数据库所花费的时间对于 15K 项目大约需要 35 分钟。
执行的更新的性能受到 UpdateBatchSize 的限制,在我的情况下为 1,当我尝试更改它时,我收到一个异常 "Specified method is not supported".
更新方法如下:
public async Task<bool> SaveTable()
{
SQLiteDataAdapter data_adapter = null;
try
{
data_adapter = new SQLiteDataAdapter(sql_cmd);
data_adapter.UpdateBatchSize = 10;
}
catch (Exception e)
{
Console.WriteLine("Exception Thrown: " + e.Message);
return false;
}
try
{
SQLiteCommandBuilder cmd_bldr = new SQLiteCommandBuilder(data_adapter);
data_adapter.InsertCommand = cmd_bldr.GetInsertCommand();
Console.WriteLine(data_adapter.InsertCommand.CommandText);
data_adapter.AcceptChangesDuringUpdate = true;
data_adapter.UpdateCommand = data_adapter.InsertCommand;
}
catch (Exception e)
{
Console.WriteLine("Exception Thrown: " + e.Message);
return false;
}
try
{
var size = data_adapter.UpdateBatchSize;
Console.WriteLine("Updating Table. Batch Size: " + size);
var rows_updated = data_adapter.Update(data_table);
Console.WriteLine("Rows Updated: " + rows_updated.ToString());
data_adapter.Dispose();
}
catch(Exception e)
{
Console.WriteLine("Exception Thrown: " + e.Message);
return false;
}
return true;
}
有什么方法可以更改 UpdateBatchSize 或增加每秒更新的数量?
我认为您使用 SQLiteDataAdapter 的方法是错误的。 UpdateBatchSize 属性 未由 SQLite 连接器实现,因此无法更改。默认值 1 表示禁用更新批处理功能。因此,当请求更新时,适配器被迫 运行 一个缓慢的一行一行的过程。
最好的方法是手动执行每个插入命令,但将它们包含在一个事务中
// Getting the command text from the SQLiteCommandBuilder, but at this
// point you could simply write it as text directly in the constructor
SQLiteCommandBuilder cmd_bldr = new SQLiteCommandBuilder(data_adapter);
using (var cmd = new SQLiteCommand(cmd_bldr.GetInsertCommand(), conn))
{
conn.Open();
// Create the parameters collection, setting the type for each
// parameter but without setting an explicit value
cmd.Parameters.Add("@p1", DbType.Int);
// create other parameters for each field to insert ....
using (var transaction = conn.BeginTransaction())
{
// Inform the command about the open transaction
cmd.Transaction = transaction;
// Loop over your table rows....
foreach(DataRow row in data_table.Rows)
{
// get the parameters value from the row's field
cmd.Parameters["@p1"].Value = row[fieldIndex];
.... repeat for other parameters ...
cmd.ExecuteNonQuery();
}
transaction.Commit();
}
}
我有一个 JSON 文件,其中包含 ~25-30K 个项目,我想将其保存在 sqlite 数据库中。 然而,SQLiteDataAdapter class 使用包含所有项目的 DataTable 对象更新数据库所花费的时间对于 15K 项目大约需要 35 分钟。 执行的更新的性能受到 UpdateBatchSize 的限制,在我的情况下为 1,当我尝试更改它时,我收到一个异常 "Specified method is not supported".
更新方法如下:
public async Task<bool> SaveTable()
{
SQLiteDataAdapter data_adapter = null;
try
{
data_adapter = new SQLiteDataAdapter(sql_cmd);
data_adapter.UpdateBatchSize = 10;
}
catch (Exception e)
{
Console.WriteLine("Exception Thrown: " + e.Message);
return false;
}
try
{
SQLiteCommandBuilder cmd_bldr = new SQLiteCommandBuilder(data_adapter);
data_adapter.InsertCommand = cmd_bldr.GetInsertCommand();
Console.WriteLine(data_adapter.InsertCommand.CommandText);
data_adapter.AcceptChangesDuringUpdate = true;
data_adapter.UpdateCommand = data_adapter.InsertCommand;
}
catch (Exception e)
{
Console.WriteLine("Exception Thrown: " + e.Message);
return false;
}
try
{
var size = data_adapter.UpdateBatchSize;
Console.WriteLine("Updating Table. Batch Size: " + size);
var rows_updated = data_adapter.Update(data_table);
Console.WriteLine("Rows Updated: " + rows_updated.ToString());
data_adapter.Dispose();
}
catch(Exception e)
{
Console.WriteLine("Exception Thrown: " + e.Message);
return false;
}
return true;
}
有什么方法可以更改 UpdateBatchSize 或增加每秒更新的数量?
我认为您使用 SQLiteDataAdapter 的方法是错误的。 UpdateBatchSize 属性 未由 SQLite 连接器实现,因此无法更改。默认值 1 表示禁用更新批处理功能。因此,当请求更新时,适配器被迫 运行 一个缓慢的一行一行的过程。
最好的方法是手动执行每个插入命令,但将它们包含在一个事务中
// Getting the command text from the SQLiteCommandBuilder, but at this
// point you could simply write it as text directly in the constructor
SQLiteCommandBuilder cmd_bldr = new SQLiteCommandBuilder(data_adapter);
using (var cmd = new SQLiteCommand(cmd_bldr.GetInsertCommand(), conn))
{
conn.Open();
// Create the parameters collection, setting the type for each
// parameter but without setting an explicit value
cmd.Parameters.Add("@p1", DbType.Int);
// create other parameters for each field to insert ....
using (var transaction = conn.BeginTransaction())
{
// Inform the command about the open transaction
cmd.Transaction = transaction;
// Loop over your table rows....
foreach(DataRow row in data_table.Rows)
{
// get the parameters value from the row's field
cmd.Parameters["@p1"].Value = row[fieldIndex];
.... repeat for other parameters ...
cmd.ExecuteNonQuery();
}
transaction.Commit();
}
}