c# - SQLite 中的慢批处理/批量插入

标签 c# .net sqlite bulkinsert

我试图将数据从 csv 文件导入到 sqlite 表中。我的测试数据只有大约 8Mb(50,000 行),大约需要 15 秒。然而生产数据将近400Mb,并且需要很长时间(至少30分钟+,我放弃了等待)。

经过大量研究,我发现需要在单个事务中执行插入(这让我得到了 15 秒的导入,很好的建议!:))所以这不是问题所在。 (据我所知)

我还根据此 Robert Simpson post 使用“参数化 INSERT 语句上的 ExecuteNonQuery()” - 以及众多变化。

我只是在使用 TextReader.ReadLine()String.Split('\t') ,然后我在某处读到关于 ReadLine() 的内容由于磁盘读取次数而变慢,所以我研究了读取 bufferedStream,并遇到了 this csv reader .但仍然没有明显的性能变化。

所以,我注释掉了我的插入循环的内容,并且读取几乎立即发生 - 所以我确信问题出在我的插入中。我已经尝试了多种创建参数化查询 + 单一事务的变体,但所有结果都几乎相同..

这是我的代码的常规版本。提前致谢,这让我抓狂!我正要尝试导入数据集并插入它?....

using (TextReader tr = File.OpenText(cFile))
{                       
    using (SQLiteConnection cnn = new SQLiteConnection(connectionString))
    {
        string line;
        string insertCommand = "INSERT INTO ImportTable VALUES (@P0,@P1,@P2,@P3,@P4)";

        cnn.Open();
        SQLiteCommand cmd = new SQLiteCommand("begin", cnn);
        cmd.ExecuteNonQuery();

        cmd.CommandText = insertCommand;

        while ((line = tr.ReadLine()) != null)
        {
            string[] items = line.Split('\t');

            cmd.Parameters.AddWithValue("@P0", items[0]);
            cmd.Parameters.AddWithValue("@P1", items[1]);
            cmd.Parameters.AddWithValue("@P2", items[2]);
            cmd.Parameters.AddWithValue("@P3", items[3]);
            cmd.Parameters.AddWithValue("@P4", items[4]);
            cmd.ExecuteNonQuery();
        }
        cmd.CommandText = "end";
        cmd.ExecuteNonQuery(); 
    }              
}

更新:我刚刚尝试使用带有参数的插入(只是硬编码了一些值),不到 5 秒......仍然没有我看到的文章那么快......

此外,我正在运行 Core2 Duo (3Ghz) 和 2G Ram,XP。

最佳答案

所以我认为我已经解决了问题 - 或者至少找到了解决方案。

因为我已经用尽了我所有的代码选项(并且看起来没有人对我的代码有答案/问题),我认为问题可能出在数据库本身......

我在 SQLite Manager Firefox 插件中创建了我的数据库和表。

所以我从 commandshell 重新创建了一切,然后 BOOM!我的导入时间缩短到只有几秒钟!

我知道它无法处理 64 位整数(但只使用 TEXT 数据类型)存在问题。使用与 .Net 版本不同的 SQLite 引擎的 SQLite Manager 可能存在问题?我不知道。

我的下一步可能是在我的应用程序中实际创建 db + 表,而不是让它们预先准备好......但我对现在的性能相当满意,所以这不是优先事项。

关于c# - SQLite 中的慢批处理/批量插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5257969/

相关文章:

mysql - 标准 SQL 以及上一行和下一行值

android - 如何检查 SQLite 文件一致性(健康检查)

c# - BinaryWriter 不采用替代参数

javascript - 防止对表单进行 XSS 攻击

c# - 从 TFS 单元测试覆盖范围中排除文件夹

c# - 从 Directory.GetFiles 中排除结果

c# - 如何保护用 .Net 编写的 API 的安全

.net - 如何将可移植类库 (PCL) 转换为普通类库?

c# - 有没有办法为 WinForms .NET 3.5 应用程序中未处理的异常定义操作?

activerecord - 如何使用 Active Record 在 Sinatra 中静音 SQLite3 记录器?