大型 SQL 插入 TVF 与 BULK 插入

发布于 2024-11-17 23:51:53 字数 830 浏览 4 评论 0原文

从 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 insert 是否有内存中的等效项。

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

What is the fastest way to insert a huge array (10M elements) from a C# application?

Till now, I used bulk insert. C# app generates a large textual file and I load it with BULK INSERT command . Out of curiosity I wrote a simple user defined CLR table value function.

[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);
        }

And this query:

INSERT INTO my_table SELECT data FROM dbo.getArray('x');

Works almost 2 times faster than bulk equivalent. The exact results are:

BULK - 330s (write to disk + insert)
TVF - 185s

Of course, this is due to write overhead, but I don't know if BULK insert have any in memory equivalent.

So my question is - is TVF better compering to the BULK (which is created for huge inserts), or am I missing something here. Is there any third alternative?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

魔法唧唧 2024-11-24 23:51:53

当我确实需要时,我使用 SqlBulkCopy最后的性能下降,这样您就可以跳过首先将其全部放入磁盘的开销。

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

据我所知,这是将数据从 C# 程序泵入 SqlDB 的最快方法。

国杰

I use a SqlBulkCopy when I really need the very last drop of performance, that way you can skip the overhead of first putting it all on disk.

The SqlBulkCopy accepts an IDataReader that you have to implement, but only a few methods of the interface. What I always do is just create the class MyBulkCopySource : IDataReader, click 'Implement interface' and feed it to the BulkCopy as is to see wich method gets called. Implement that, try again etc. You only need to implement three of four of them, the rest never gets called.

AFAIK this is the fastest way to pump data from a C# program into a SqlDB.

GJ

蹲墙角沉默 2024-11-24 23:51:53
  • 使用 SqlBulkCopy
  • 从多个线程中每次使用 30.000 行等块。
  • 不是到最终表,而是到临时表
  • ,使用不支持锁的连接设置从中进行复制。

这完全在茶几上设置了最小的锁定。

  • Use SqlBulkCopy
  • From multiple threads with blocks like 30.000 rows each time.
  • NOT to the final table, but to a temporary table
  • From which you copy over, using a connection setting that does not honor locks.

This totally puts the smallest locking on the end table.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文