【问题标题】:C# Optimisation: Inserting 200 million rows into databaseC# 优化:向数据库中插入 2 亿行
【发布时间】:2011-02-01 07:58:26
【问题描述】:

我想优化以下(简化的)代码以提高速度:

long inputLen = 50000000; // 50 million 
DataTable dataTable = new DataTable();
DataRow dataRow;
object[] objectRow;
while (inputLen--)
{
    objectRow[0] = ...
    objectRow[1] = ...
    objectRow[2] = ...

    // Generate output for this input
    output = ...

    for (int i = 0; i < outputLen; i++) // outputLen can range from 1 to 20,000
    {
         objectRow[3] = output[i];
         dataRow = dataTable.NewRow();
         dataRow.ItemArray = objectRow;
         dataTable.Rows.Add(dataRow);
    }
}

// Bulk copy
SqlBulkCopy bulkTask = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, null);
bulkTask.DestinationTableName = "newTable";
bulkTask.BatchSize = dataTable.Rows.Count;
bulkTask.WriteToServer(dataTable);
bulkTask.Close();

我已经在使用 SQLBulkCopy 来尝试加快速度,但是将值分配给 DataTable 本身似乎很慢。

我不知道 DataTables 是如何工作的,所以我想知道我是否会通过首先创建一个可重用数组,然后将其分配给 DataRow,然后将 DataRow 添加到 DataTable 来创建不必要的开销?还是首先使用 DataTable 不是最优的?输入来自数据库。

我不太关心 LOC,只关心速度。谁能给点建议?

【问题讨论】:

  • 实现示例看SimpleDataReaderhere

标签: c# datatable sqlbulkcopy


【解决方案1】:

对于这么大的桌子,你应该改用

public void WriteToServer(IDataReader reader)

方法。

这可能意味着你必须用你的代码实现一个“假”IDataReader 接口(如果你没有从现有的IDataReader 获取数据),但是这样你会得到从端到端“流式传输”,将避免 2 亿循环。

【讨论】:

  • 这是否意味着 SQLBulkCopy 仍然可以有效地写入数据库因为正在构造行?输入来自同一个数据库,但对于每一行,我可能会创建 20000 个新的。
  • @Box9:是的,在调用 SQLBulkCopy 之前数据不需要存在。我们在这里有一个“Legacy data take on”应用程序,它将在大约一个小时内移植 100 万行(BCP 输出 1 个表,格式化多个 bcp 文件,bcp 那些文件)。我们最近需要它在大约 4400 万行上运行,我通过实现几个 IDataReader 从源数据库读取数据并按照 SQLBulkCopy 的要求对行进行格式化,从而将 1 小时缩短到 10 分钟。
【解决方案2】:

我建议不要在内存中保存一个巨大的数据表,而是实现一个IDataReader,它在批量复制时提供数据。这将减少将所有内容预先保存在内存中的需要,因此应该有助于提高性能。

【讨论】:

    【解决方案3】:

    您不应该在内存中构建整个数据表。使用 WrtieToServer 的 overload,它采用 DataRow 数组。只需将您的数据分成几块即可。

    【讨论】:

    • 那个方法不是还在内存中构造吗?此外,如果我没有耗尽内存,那么在内存中构建它不是最快的吗?
    • 如果你一次只构造 1k 行而不是 200m,那么内存管理器保存这么多的数据会容易得多。除此之外,您几乎肯定会一次与内存中保存的 200m 记录进行交换
    猜你喜欢
    • 2023-04-10
    • 2011-09-24
    • 2021-01-28
    • 2014-02-01
    • 1970-01-01
    • 2019-06-21
    • 2013-08-17
    • 1970-01-01
    • 2012-10-13
    相关资源
    最近更新 更多