我有以下(简化)代码,我想优化速度:
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,只关心速度。任何人都可以就此提出一些建议吗?
答案 0 :(得分:13)
对于这么大的表,你应该使用
public void WriteToServer(IDataReader reader)
方法
这可能意味着您必须使用代码实现自己的“假”IDataReader
界面(如果您没有从现有IDataReader
获取数据),但这样做,你将从头到尾获得“流媒体”,并将避免2亿次循环。
答案 1 :(得分:4)
我建议不要在内存中保存一个巨大的数据表,而是建议实现一个IDataReader
,在批量复制过程中提供数据。这样可以减少将所有内容保留在内存中的需要,从而有助于提高性能。
答案 2 :(得分:0)
您不应该在内存中构造整个数据表。使用这个带有DataRow数组的overload WrtieToServer。只需将数据分成几部分。