我有一组 30 个文件。我遍历这些文件,并为每个文件插入 1529 行,大约 30 列,219487 行,大约 6 列。
我在 C# 中执行此操作,并通过数据表插入(见底部)。对于 1529 行(30 列),我将插入分组为每批 1,300 行,对于 219,487 行(6 列),每批插入 50000 行。
插入每个批次时,没有多线程 - 一切都是顺序的(至少在我的代码中)。在我的代码行完成插入前一个文件之前,我不会从下一个文件开始。
考虑到这一点,我希望 SQL 服务器在恒定时间内完成每个文件(文件非常相似,总是插入 1529 和 219487)。
但是,每个文件的每个 SQL 插入所花费的时间线性增加 - 从第一个文件的 9 秒到第 30 个文件的 50 秒。我已将 CPU 时间与所用的 SQL 时间分开,一开始插入 6 列行之一需要 0.000033 秒。接近尾声,对于后面的文件,对于 6 列数据,所用时间为 0.000228。也就是说,插入219487行(6列)数据的时间增加了约7倍?
我将批量大小减少到 20000 并且没有任何区别。在过去,我相信我将其减少到 5000 和 10000,但仍然没有任何区别。我对底层 SQL 架构了解不多,所以我有点迷茫。
我觉得我正在超载 SQL 服务器。但是,是否给人的印象是这是按顺序完成的,而不是给 SQL 服务器分配作业?SQL 请求可能是通过线程产生的,但是我将批处理大小减少到 100(请参见下文),但这仍然没有帮助。完成的总时间更长,但每个文件仍然线性增加。
我已将批处理大小减少到 100(只是为了确保服务器不会超载)并且我仍然看到线性增加的时间?
在整个过程中,我一直指的是 SQL 插入所花费的时间,而不是每个文件的 SQL + CPU 时间的总和。
可能不可能确切地告知正在发生的事情,但我可以有一些提示和事情绝对避免以最好地解决这个问题吗?
我的 SQL 插入代码(每批插入调用)是:
private static void WriteResultsToDatabase(string tableName, DataTable tableToWrite)
{
using (SqlConnection connection =
new SqlConnection(connectionString))
{
SqlBulkCopy bulkCopy =
new SqlBulkCopy
(
connection,
SqlBulkCopyOptions.TableLock |
SqlBulkCopyOptions.FireTriggers |
SqlBulkCopyOptions.UseInternalTransaction,
null
);
bulkCopy.DestinationTableName = tableName;
for (int i = 0; i < tableToWrite.Columns.Count; i++)
bulkCopy.ColumnMappings.Add(tableToWrite.Columns[i].ColumnName, tableToWrite.Columns[i].ColumnName);
try
{
connection.Open();
bulkCopy.WriteToServer(tableToWrite);
}
finally
{
connection.Close();
}
}
}