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