将数百万行插入SQL Server数据库的最佳方法

时间:2015-06-23 16:01:06

标签: c# sql-server entity-framework

我正在从多个供稿中收集数据,包括api,excel文件,文本文件,word文件。我使用关系数据库来存储所有关系。最多有10个一对多或多对多的关系。

我正在使用的方法是将每个条目写入mysql> CREATE BITMAP INDEX ON tb1(num); ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'BITMA P INDEX ON tb1(num)' at line 1 文件,然后调用存储过程来批量插入所有条目。所以在这种情况下,我的数据库中的每个表都可以有10个单独的文件。

我遇到了两个问题:

  • 将文件传输到数据库服务器(同一网络)
  • 主键,我需要使用guid而不是自动增量

性能的最佳方法是什么?

2 个答案:

答案 0 :(得分:5)

2个字:BULK INSERT

如果您已经有一个csv文件,这只是编写一些SQL或C#(您喜欢的)来执行批量插入的情况。

以下是SQL文档:https://msdn.microsoft.com/en-gb/library/ms188365.aspx

BULK INSERT MySchema.MyTable
FROM 'c:\myfile.csv'
WITH 
  (
     FIELDTERMINATOR =',',
     ROWTERMINATOR ='\n'
  );

C#docs:https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy%28v=vs.110%29.aspx

答案 1 :(得分:0)

我为https://github.com/MikaelEliasson/EntityFramework.Utilities#batch-insert-entities构建了一个小工具 或Nuget链接https://www.nuget.org/packages/EFUtilities/

它将使用内存列表中的SqlBulkCopy。它使用EF元数据,因此您无需自己配置。代码如下所示:

using (var ctx = new Context())
{
    EFBatchOperation.For(ctx, ctx.Locations).InsertAll(locations);
}

这是我制作的一个小型演示https://github.com/MikaelEliasson/EFUtilitiesDemos/blob/master/BulkInsertAndUpdate/Program.cs#L46

速度很大程度上取决于您的实体的位数。我的测试显示我可以为中型实体插入~100 000个对象/秒。

如果你有guid,关系插入应该像你已经做的那样相当容易。

因为您有多个插入,我建议您使用事务范围。见https://github.com/MikaelEliasson/EntityFramework.Utilities/issues/26

修改

如果您更喜欢使用将包含在下一版本中的int或long。这将花费更长的时间,但您可以为商店生成的ID启用Id返回。

请参阅:https://github.com/MikaelEliasson/EntityFramework.Utilities/blob/release20/EntityFramework.Utilities/Tests/InsertTests.cs#L125

该代码现在正在运行,但发布尚未就绪。但是如果你想现在就试试,你可以自己下载并构建realease20分支。