【问题标题】:what is the fastest way to populate SQLite table from a datatable从数据表中填充 SQLite 表的最快方法是什么
【发布时间】:2018-08-13 20:08:42
【问题描述】:

在 C# .net 2 中从 DataTable 填充 SQLite 数据库的最快方法是什么。

目前我正在为表中的每一行构建插入语句。我已经尝试过数据适配器,但速度似乎并没有更快。目前循环 20,000 行并将它们写入数据库需要 5 分钟。 有什么建议吗?

解决方案:

我发现使用 BEGIN...COMMIT 包围的插入语句块对我有显着的速度提升:

BEGIN;
INSERT INTO friends (name1,name2) VALUES  ('john','smith');
INSERT INTO friends (name1,name2) VALUES  ('jane','doe');
COMMIT;

我的插入语句每个大约 500 字节,因此我将每个事务的语句数限制为 100 个。

【问题讨论】:

    标签: c# sqlite


    【解决方案1】:

    从 SQLite 网站查看此常见问题解答条目:

    http://www.sqlite.org/faq.html#q19

    默认情况下,每个 INSERT 语句都是它自己的事务。但是如果你用 BEGIN...COMMIT 包围多个 INSERT 语句,那么所有的插入都会被分组到一个事务中。提交事务所需的时间在所有封闭的插入语句中分摊,因此每个插入语句的时间大大减少。

    【讨论】:

    • 有趣。我想知道 BEGIN ... COMMIT 块周围有多少语句
    • 您可以使用 7200 RPM 硬盘驱动器每秒执行 60 次事务。将写入速度(例如 5MB/s)除以 60 得到每个事务的字节数,然后将其除以记录大小得到每个事务的插入数。
    【解决方案2】:

    this thread

    最好的方法是使用ExecuteNonQuery(),它会一次性提交所有的插入,而不必一直分配字符串。 20,000 行应该花费不到一分钟的时间。

    【讨论】:

      【解决方案3】:

      考虑使用 SqlLiteDataAdapter。 (我仍然必须使用 vb.net 但下面的示例应该很容易翻译。或者看看原始来源:http://stackoverflow.com/a/2671511

      Private Sub FillDatabaseTableWithDataTable(dataTable As DataTable)
                  ' inspired by http://stackoverflow.com/a/2671511
      
                  ' Query the destination database
                  Dim query As String = $"SELECT * FROM `{dataTable.TableName}`"
      
                  Using adapter As New SQLiteDataAdapter(query, Connection)
      
                      Using commandBuilder = New SQLiteCommandBuilder(adapter)
      
                          Connection.Open()
      
                          commandBuilder.QuotePrefix = "["
                          commandBuilder.QuoteSuffix = "]"
                          commandBuilder.GetInsertCommand()
      
                          'Create an empty "destination" table for synchronization
                          ' with SqLite "source" database
                          Dim destinationTable As New DataTable()
      
                          'load data from SqLite "source" database to destination table, e.g.
                          'column headers
                          adapter.Fill(destinationTable)
      
                          'adapt "destination" table: fill data
                          For Each row As DataRow In dataTable.Rows
                              Dim destinationRow As DataRow = destinationTable.NewRow()
                              destinationRow.ItemArray = row.ItemArray
                              destinationTable.Rows.Add(destinationRow)
                          Next
      
                          'Update SqLite source table
                          'the Update has To be wrapped In a transaction
                          'Otherwise, SQLite would implicitly create a transaction
                          'for each line. That would slow down the writing process.
                          Using transaction = Connection.BeginTransaction()
                              adapter.Update(destinationTable)
                              transaction.Commit()
                          End Using
      
                          Connection.Close()
                      End Using
                  End Using
              End Sub
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-26
        相关资源
        最近更新 更多