从C#应用程序中插入一个巨大数组(10M个元素(的最快方法是什么?
到目前为止,我使用批量插入。C#应用程序生成一个大的文本文件,我用BULK INSERT
命令加载它。出于好奇,我编写了一个简单的用户定义CLR表值函数。
[SqlFunction(Name = "getArray", FillRowMethodName = "FillRow")]
public static IEnumerable getArray(String name)
{
return my_arrays[name]; // returns the array I want to insert into db
}
public static void FillRow(Object o, out SqlDouble sdo)
{
sdo = new SqlDouble((double)o);
}
这个查询:
INSERT INTO my_table SELECT data FROM dbo.getArray('x');
工作速度几乎是批量等效产品的2倍。确切的结果是:
BULK-330秒(写入磁盘+插入(TVF-185s
当然,这是由于写入开销,但我不知道BULK插入在内存中是否有等效项。
所以我的问题是,TVF是否更适合BULK(它是为巨大的插入而创建的(,或者我在这里错过了什么。还有第三种选择吗?
当我真的需要最后一点性能时,我会使用SqlBulkCopy,这样你就可以跳过首先将其全部放在磁盘上的开销。
SqlBulkCopy接受必须实现的IDataReader,但只接受接口的少数方法。我一直做的就是创建class MyBulkCopySource : IDataReader
,单击"Implement interface"并按原样将其提供给BulkCopy,以查看调用了哪个方法。实现它,再试一次等等。你只需要实现其中四个中的三个,其余的永远不会被调用。
AFAIK这是将数据从C#程序泵送到SqlDB的最快方法。
GJ
- 使用SqlBulkCopy
- 来自多个线程,每次具有类似30.000行的块
- 不是最后一张桌子,而是临时桌子
- 使用不尊重锁定的连接设置从中复制
这完全把最小的锁放在了最后一张桌子上。