我将大量记录加载到我的应用程序中(100万+)并对它们进行大量处理。处理要求它们都在内存中。
之后,我想将所有(现在已修改的)记录转储到空表中。
加载记录仅需几秒钟,我最终得到了大量MyRecord
个项目。
使用SqlBulkCopy
保存也需要几秒钟。
但是SqlBulkCopy
要求(我相信)DataTable
- 将我的记录加载到DataTable
的速度很慢 - 每分钟大约7500条记录
dataTable.Rows.Add(myRecord.Name, myRecord.Age, ....)
有更快的方法来执行这个中间步骤吗?
答案 0 :(得分:6)
导致延迟的原因是您必须先将所有内容缓冲到DataTable中,然后再将其发送到服务器。为了获得更好的性能,您应该立即将记录发送到SqlBulkCopy,并让该类使用自己的缓冲和批处理。
SqlBulkCopy可以与IDataReader一起使用。所有ADO.NET数据读取器都实现了此接口,因此您可以将从任何数据读取器读取的数据推送到SqlBulkCopy。
在其他情况下,假设您有一个IEnumerable对象,您可以使用来自FastMember包的Marc Gravel的ObjectReader在IEnumerable之上创建一个IDataReader。此数据读取器不一次加载所有内容,因此在SqlBulkCopy请求之前不会缓存任何数据:
复制Marc Gravel的例子:
IEnumerable<SomeType> data = ...
using(var bcp = new SqlBulkCopy(connection))
using(var reader = ObjectReader.Create(data, "Id", "Name", "Description"))
{
bcp.DestinationTableName = "SomeTable";
bcp.WriteToServer(reader);
}
答案 1 :(得分:0)
我不知道问题是什么。下面的程序运行不到一秒钟。我怀疑速度慢是由于读取数据而不是写入DataTable。
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("Col A", typeof(int));
dt.Columns.Add("Col B", typeof(string));
dt.Columns.Add("Col C", typeof(int));
dt.Columns.Add("Col D", typeof(string));
dt.Columns.Add("Col E", typeof(int));
dt.Columns.Add("Col F", typeof(string));
dt.Columns.Add("Col G", typeof(int));
dt.Columns.Add("Col H", typeof(string));
dt.Columns.Add("Col I", typeof(int));
dt.Columns.Add("Col J", typeof(string));
DateTime begin = DateTime.Now;
for (int i = 0; i < 7500; i++)
{
dt.Rows.Add(new object[] {
i + 10000, "b", i + 20000, "d", i + 30000, "f", i + 40000, "h", i + 50000, "i"
});
}
DateTime end = DateTime.Now;
Console.WriteLine((end - begin).ToString());
Console.ReadLine();
}