10

我正在使用此代码将 100 万条记录插入数据库中的空表中。好的,所以没有太多代码,我将从已经与数据交互的点开始,并将架构读入DataTable

所以:

DataTable returnedDtViaLocalDbV11 = DtSqlLocalDb.GetDtViaConName(strConnName, queryStr, strReturnedDtName);

现在我们已经returnedDtViaLocalDbV11创建了一个新DataTable的作为源数据库表的克隆:

DataTable NewDtForBlkInsert = returnedDtViaLocalDbV11.Clone();

Stopwatch SwSqlMdfLocalDb11 = Stopwatch.StartNew();
NewDtForBlkInsert.BeginLoadData();

for (int i = 0; i < 1000000; i++)
{
   NewDtForBlkInsert.LoadDataRow(new object[] { null, "NewShipperCompanyName"+i.ToString(), "NewShipperPhone" }, false);
}
NewDtForBlkInsert.EndLoadData();

DBRCL_SET.UpdateDBWithNewDtUsingSQLBulkCopy(NewDtForBlkInsert, tblClients._TblName, strConnName);

SwSqlMdfLocalDb11.Stop();

var ResSqlMdfLocalDbv11_0 = SwSqlMdfLocalDb11.ElapsedMilliseconds;

此代码在 5200ms 内将 100 万条记录填充到嵌入式 SQL 数据库 (localDb )。其余代码只是实现 bulkCopy 但无论如何我都会发布它。

 public string UpdateDBWithNewDtUsingSQLBulkCopy(DataTable TheLocalDtToPush, string TheOnlineSQLTableName, string WebConfigConName)
 {
    //Open a connection to the database. 
    using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings[WebConfigConName].ConnectionString))
    {
       connection.Open();

       // Perform an initial count on the destination table.
       SqlCommand commandRowCount = new SqlCommand("SELECT COUNT(*) FROM "+TheOnlineSQLTableName +";", connection);
       long countStart = System.Convert.ToInt32(commandRowCount.ExecuteScalar());

       var nl = "\r\n";
       string retStrReport = "";
       retStrReport = string.Concat(string.Format("Starting row count = {0}", countStart), nl);
       retStrReport += string.Concat("==================================================", nl);
       // Create a table with some rows. 
       //DataTable newCustomers = TheLocalDtToPush;

       // Create the SqlBulkCopy object.  
       // Note that the column positions in the source DataTable  
       // match the column positions in the destination table so  
       // there is no need to map columns.  
       using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
       {
          bulkCopy.DestinationTableName = TheOnlineSQLTableName;

          try
          {
             // Write from the source to the destination.
             for (int colIndex = 0; colIndex < TheLocalDtToPush.Columns.Count; colIndex++)
             {
                bulkCopy.ColumnMappings.Add(colIndex, colIndex);
             }
             bulkCopy.WriteToServer(TheLocalDtToPush);
          }

          catch (Exception ex)
          {
             Console.WriteLine(ex.Message);
          }
       }

       // Perform a final count on the destination  
       // table to see how many rows were added. 
       long countEnd = System.Convert.ToInt32(
       commandRowCount.ExecuteScalar());

       retStrReport += string.Concat("Ending row count = ", countEnd, nl);
       retStrReport += string.Concat("==================================================", nl);
       retStrReport += string.Concat((countEnd - countStart)," rows were added.", nl);
       retStrReport += string.Concat("New Customers Was updated successfully", nl, "END OF PROCESS !");
       //Console.ReadLine();
       return retStrReport;
   }
}

通过与 SQL 服务器的连接进行尝试大约需要 7000 毫秒(最多)和平均约 7700 毫秒。同样通过一个随机的 kv nosql 数据库大约需要 40 秒(实际上我什至没有记录它,因为它通过了 x2 的 sql 变体)。那么......有没有比我在代码中测试的更快的方法?

编辑

我使用的是win7 x64 8gb ram,最重要的是我认为(因为i5 3ghz)现在还不是很好,Raid-0上的x3 500Gb Wd做得更好,但我只是说你是否会检查你的电脑只需将其与配置中的任何其他方法进行比较

4

8 回答 8

2

你试过SSIS吗?我从未编写过带有 loacldb 连接的 SSIS 包,但这是 SSIS 应该非常适合的那种活动。

如果您的数据源是 SQL Server,另一个想法是设置链接服务器。不确定这是否适用于 localdb。如果您可以设置链接服务器,则可以一起绕过 C# 并使用 INSERT .. SELECT ... FROM ... SQL 语句加载数据。

于 2013-06-25T12:32:27.070 回答
1

你可以使用Dapper.NET. Dapper 是一个微 ORM,执行查询并将结果映射到强类型列表。计算机软件中的对象关系映射(ORM、O/RM 和 O/R 映射)是一种编程技术,用于在面向对象编程语言中的不兼容类型系统之间转换数据。这实际上创建了一个可以在编程语言中使用的“虚拟对象数据库”

欲了解更多信息:

查看https://code.google.com/p/dapper-dot-net/

GitHub 存储库: https ://github.com/SamSaffron/dapper-dot-net 希望对您有所帮助..

于 2013-07-10T14:41:07.003 回答
1

删除循环...在 SQL 中,尝试创建一个包含 100 万行的表...并将其左连接用于插入/选择数据

于 2013-07-16T03:43:39.323 回答
0

为要保存到数据库中的所有行创建一个 XML 文件。将此 XML 传递给 SQL 存储过程并仅在一次调用中保存所有记录。但是必须编写您的存储过程,以便它可以读取所有读取然后插入到表中。

于 2013-07-15T11:31:04.190 回答
0

尝试发送它而不将其存储在数据表中。

请参阅本文末尾的示例,它允许您使用枚举器http://www.developerfusion.com/article/122498/using-sqlbulkcopy-for-high-performance-inserts/

于 2013-06-27T01:22:52.647 回答
0

如果您只是在创建无意义的数据,请创建一个存储过程并通过 .net 调用它

如果您要传递真实数据,再次将其传递给存储过程会更快,但最好不要删除表并使用数据重新创建它。

如果一次插入一行,它会比一次插入所有需要更长的时间。如果您有要编写的索引,则需要更长的时间。

于 2013-06-28T19:20:30.367 回答
0

我同意 Mike 关于 SSIS 的观点,但它不适合您的环境,但是对于涉及跨服务器调用和一般数据流过程的 ETL 过程,它是一个很好的内置工具并且高度集成。

对于 100 万行,您可能需要进行批量插入。根据行大小,除非您分批执行此操作,否则您将无法真正使用存储过程。数据表将很快填满内存,同样取决于行大小。您可以创建一个存储过程,并使其采用表类型并每隔 X 行调用一次,但是当您已经有了更好、更具可扩展性的解决方案时,我们为什么要这样做。明年这一百万行可能会达到 5000 万行。

我已经使用了一点 SSIS,如果这适合组织,我会建议查看它,但这不是一次性的答案,不值得依赖。

于 2013-07-18T00:07:52.120 回答
0

如果这是一个新项目,我建议您使用Entity Framework。在这种情况下,您可以使用包含所需所有数据的对象创建一个 List<>,然后简单地将其完全添加到相应的表中。通过这种方式,您可以快速获取所需的数据,然后立即将其发送到数据库。

于 2013-07-15T13:17:23.420 回答