2

我试图找出通过 SQL Server 中的迷你控制台应用程序执行批量更新的最佳方法。我已经编写了自己的批量更新方式,如下所示:

  SqlCommand command = new SqlCommand();
  command.Connection = new SqlConnection("Data Source=.;Initial Catalog=mydb;Integrated Security=SSPI");
  command.Connection.Open();

  for (int i = 0; i < items.Count; i = i + 1000)
  {
     var batchList = items.Skip(i).Take(1000).ToList();
     for (int j = 0; j < batchList.Count(); j++)
     {
       command.CommandText += string.Format("update Items set QuantitySold=@s_id{0} where ItemID = @id{0};", j);
       command.Parameters.AddWithValue("@s_id" + j, batchList[j].QuantitySold);
       command.Parameters.AddWithValue("@id" + j, batchList[j].ItemID);
      }
     command.ExecuteNonQuery();
     command = new SqlCommand();
     command.Connection = new SqlConnection("Data Source=.;Initial Catalog=mydb;Integrated Security=SSPI");
     command.Connection.Open();
            }
     command.Connection.Close();

但是我对这个的性能不太满意,更新我的数据库中的 50000-100000 条记录在这样做时会变得很慢,即使它是分批 1000 条......

有没有可以“加快速度”的库/解决方案?

有人可以帮我吗 ?

4

3 回答 3

6

最快的方法是使用内置类将数据批量插入SqlBulkCopy临时表,然后使用连接更新到该表

或者您可以使用诸如SqlBulkTools 之类的工具,它以一种简单的方式完成此操作。

var bulk = new BulkOperations();

using (TransactionScope trans = new TransactionScope())
{
    using (SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=mydb;Integrated Security=SSPI")
    {
        bulk.Setup()
            .ForCollection(items)
            .WithTable("Items")
            .AddColumn(x => x.QuantitySold)
            .BulkUpdate()
            .MatchTargetOn(x => x.ItemID) 
            .Commit(conn);
    }

    trans.Complete();
}
于 2017-05-24T19:08:36.933 回答
1

您可以使用Kros.KORM进行批量操作。

using (var database = new Database("connectionstring ...", "ado client name ..."))
{
    database
       .Query<Movie>()
       .AsDbSet()
       .BulkUpdate(_data);
}

或者,如果您不需要使用 ORM 并且有可用的源数据阅读器,则可以使用SqlServerBulkInsert/SqlServerBulkUpdateMsAccessBulkInsert/MsAccessBulkUpdate类来执行批量操作。

例如:

using (var bulkInsert = new SqlServerBulkInsert("connection string"))
{
    bulkInsert.Insert(reader);
}

您可以查看与纯 ADO.NET 命令的比较https://github.com/Kros-sk/Kros.Libs/wiki

于 2018-05-02T11:41:39.917 回答
0

我不知道您的代码中有哪些项目,所以我不知道如何将这些项目放入表值参数中。如果您需要,我可以提供帮助,但我需要知道那个对象是什么。

无论如何,您都可以在 sql 端做这样的事情。然后,您只需使用您的项目集合作为入站参数执行此过程。

create type Items as TABLE
(
    ItemID int
    , Quantity int
)

GO

create procedure UpdateItemsBulk
(
    @Items Items READONLY
) as

    set nocount on;

    Update i
    set QuantitySold = items.Quantity
    from items i
    join @Items items on items.ItemID = i.ItemID

GO
于 2017-05-24T19:09:54.483 回答