【问题标题】:Use of SqlBulkInsert in production applications在生产应用程序中使用 SqlBulkInsert
【发布时间】:2012-02-04 11:11:22
【问题描述】:

我们目前正在开发一个应用程序,该应用程序在每个用户会话的特定表中生成超过 5-10,000 行数据。目前我们正在使用 sql 文本命令一次插入每一行数据,因此保存操作可能需要一分钟。我们正在使用 SqlBulkInserts 并且已经看到时间下降到不到 500 毫秒。是否有人反对在许多用户将使用系统的生产应用程序中使用 SqlBulkInserts?

【问题讨论】:

    标签: c# sql database bulkinsert sqlbulkcopy


    【解决方案1】:

    我从来没有遇到过设置了 tableLock 选项的 SqlBulkCopy 问题,并且另一个用户因此而被阻止。 TableLock 选项提高了插入的效率,正如许多人所谈论的那样,并且只是简单地使用它就向我展示了。

    我的典型方法:

    public void Bulk(String connectionString, DataTable data, String destinationTable)
    {
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            using (SqlBulkCopy bulkCopy =
                new SqlBulkCopy
                (
                connection,
                SqlBulkCopyOptions.TableLock |
                SqlBulkCopyOptions.FireTriggers |
                SqlBulkCopyOptions.UseInternalTransaction,
                null
                ))
            {
                bulkCopy.BatchSize = data.Rows.Count;
                bulkCopy.DestinationTableName = String.Format("[{0}]", destinationTable);
                connection.Open();
                bulkCopy.WriteToServer(data);
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      在使用 SqlBulkInsert 实施之前,请尝试动态创建您的 INSERT 查询,使其如下所示:

      insert into MyTable (Column1, Column2)
      select 123, 'abc'
      union all
      select 124, 'def'
      union all
      select 125, 'yyy'
      union all
      select 126, 'zzz'
      

      这将只是一个数据库调用,它应该运行得更快。对于 SQL 字符串连接,请确保使用 StringBuilder 类。

      【讨论】:

      • 我确实接受了这个想法,但我对这种方法的问题是我需要为服务器上的主键创建的标识值,因为我们正在构建层次结构树,因为这是一个自引用表.
      • 那又怎样?这也完全排除了使用 SqlBulkCopy - 如果您需要返回服务器生成的 ID,您如何进行批量插入?答案是正确的,你的表扬与你自己的说法相矛盾。
      • 你说得对,我是个白痴。我们在 SqlBulkCopy 实现中所做的是检索我们刚刚在树的每个级别插入的数据列表,以检索生成的 id 列表。我什至没有想过用你上面提供的语句做同样的事情。
      【解决方案3】:

      如果您的应用程序确实需要在每个会话中生成那么多记录,我认为这是正确的方法。

      【讨论】:

      • 由于我们数据库的结构方式,我们有 12 个表在单个事务中存储数据,因此我们在使用 SqlBulkCopy 时遇到了死锁错误。通过设置 SqlBulkCopyOptions.TableLock 死锁消失了。锁定表以进行批量插入有什么缺点吗?是否会伤害尝试同时运行交易的其他用户?
      • 你的意思是除了你有一个表锁吗?接下来你来抱怨有表锁;)死锁是另一回事,它表明你的编程做得不好 - 当问题发生时解决问题,不要把坏代码放在坏代码上以避免症状。
      • 我完全同意你的看法,如果我没有一个产品经理在我背后大喊大叫,不要改变关于数据库模式的任何事情,除了一些索引,让一切表现得更好。整个情况我已经完全慌了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-21
      • 1970-01-01
      • 2015-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多