大型SQL插入TVF与BULK插入

时间:2011-06-30 08:23:48

标签: sql sql-server insert clr bulkinsert

从C#应用程序插入大型数组(10M元素)的最快方法是什么?

直到现在,我使用了批量插入。 C#app生成一个大文本文件,我用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 - 330s(写入磁盘+插入)   TVF - 185s

当然,这是由于写入开销,但我不知道BULK插入是否有任何内存等效。

所以我的问题是 - TVF是否更好地支持BULK(为大量插入而创建),或者我在这里遗漏了一些东西。有没有第三种选择?

2 个答案:

答案 0 :(得分:3)

当我真的需要最后一滴性能时,我使用SqlBulkCopy,这样你就可以省去先把它全部放在磁盘上的开销。

SqlBulkCopy接受您必须实现的IDataReader,但只接受该接口的几种方法。我一直在做的只是创建class MyBulkCopySource : IDataReader,单击“实现界面”并将其提供给BulkCopy,以便查看该方法被调用。实现,再试一次等​​。你只需要实现四个中的三个,其余的永远不会被调用。

AFAIK这是将数据从C#程序泵入SqlDB的最快方法。

GJ

答案 1 :(得分:2)

  • 使用SqlBulkCopy
  • 每次使用块数为30.000行的多个线程。
  • 不是决赛桌,而是临时桌
  • 使用不遵守锁定的连接设置从中复制。

这完全将最小的锁定放在终端表上。