简体   繁体   English

减少处理大量数据时的插入语句时间

[英]reducing insert statement time when dealing with large amount of data

I read about SqlBulkCopy and the way it can reduce the amount of time used when inserting large amount of rows my scenario is : I have a an excel file wish I convert it into a dataTable then I send this dataTable to a stored procedure ( wish I can't change its code ) that insert all the rows in the dataTable to an sql table in the database 我读到有关SqlBulkCopy的信息,它可以减少插入大量行时所用时间的方式,我的情况是:我有一个excel文件,希望将其转换为dataTable,然后将此dataTable发送到存储过程(希望我无法更改其代码),将dataTable中的所有行插入数据库中的sql表

the problem is that I have like 10 000 to 50 000 rows to insert is there any work around to reduce the time took by the stored procedure ? 问题是我要插入1万到5万行,是否有什么办法可以减少存储过程所花费的时间?

The best way to do this would be to use SqlBulkCopy to add the data to a temporary table and then feed that data into the stored proc. 最好的方法是使用SqlBulkCopy将数据添加到临时表中,然后将其提供给存储的proc。 You will need to write some SQL code to do the processing but the performance benefits of doing it this way should be worth the effort. 您将需要编写一些SQL代码来进行处理,但是以这种方式执行所带来的性能好处应该值得付出。

If you create a new stored proc then you have the added benefit of running all of this code inside the database engine so you will not be switching back and forth between your application and the DB engine. 如果创建一个新的存储过程,那么您将具有在数据库引擎内部运行所有这些代码的额外好处,因此您将不会在应用程序和数据库引擎之间来回切换。

Some Code: 一些代码:

    var importData = new DataSet();
    xmlData.Position = 0;
    importData.ReadXml(xmlData);

    using (var connection = new SqlConnection(myConnectionString))
    {
      connection.Open();
      using (var trans = connection.BeginTransaction())
      {
        using (var sbc = new SqlBulkCopy(connection, SqlBulkCopyOptions.Default, trans) { DestinationTableName = myTableName })
        {
          foreach (DataColumn col in importData.Tables[0].Columns)
          {
            sbc.ColumnMappings.Add(col.ColumnName, col.ColumnName);
          }

          sbc.WriteToServer(importData.Tables[0]); //table 0 is the main table in this dataset

          // Now lets call the stored proc.
          var cmd = new SqlCommand("ProcessDataImport", connection)
              {
                CommandType = CommandType.StoredProcedure
              };
          cmd.CommandTimeout = 1200;
          cmd.ExecuteNonQuery();

          trans.Commit();
        }
        connection.Close();
        return null;
      }
    }

Where XmlData is a stream with the Xml data matching your bulk import and myTableName contains the table you want to import into. 其中XmlData是具有与批量导入匹配的Xml数据的流,而myTableName包含要导入到的表。 Rememeber, when doing a bulk copy, the column names must match 100%. 记住,进行批量复制时,列名必须匹配100%。 Case is important too. 案例也很重要。

The proc would look something like this: 该过程看起来像这样:

CREATE PROCEDURE [ProcessDataImport]
AS
BEGIN
  DECLARE @IMPORTCOL INT

  WHILE EXISTS (SELECT X FROM TEMPTABLE)
  BEGIN
    SELECT @IMPORTCOL = (SELECT TOP 1 COLUMN1 FROM TEMPTABLE)
    EXEC DOTHEIMPORT @IMPORTCOL
    DELETE FROM TEMPTABLE WHERE COLUMN1 = @IMPORTCOL
  END
END

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM