Sql批量复制内存问题

sun*_*ine 4 c# sql sql-server

我们在C#中使用SqlBulk Copy类.在sql中插入批量数据.我们有一张表,里面有1000万条记录.

我们在循环中以10,000个批量插入数据

我们正面临物理内存问题.内存增加而且不会减少.

以下是我们的代码.我们如何在使用sql批量复制时释放内存,或者是否有其他方法可以进行批量插入.

using (System.Data.SqlClient.SqlBulkCopy bulkCopy = new System.Data.SqlClient.SqlBulkCopy(SQlConn,SqlBulkCopyOptions.TableLock,null))
{
    //bulkCopy = new System.Data.SqlClient.SqlBulkCopy(SQlConn);
    bulkCopy.DestinationTableName = DestinationTable;
    bulkCopy.BulkCopyTimeout = 0;
    bulkCopy.BatchSize = dt1.Rows.Count;
    Logger.Log("DATATABLE FINAL :" + dt1.Rows.Count.ToString(), Logger.LogType.Info);
    if (SQlConn.State == ConnectionState.Closed || SQlConn.State == ConnectionState.Broken)
        SQlConn.Open();
    bulkCopy.WriteToServer(dt1); //DataTable
    SQlConn.Close();
    SQlConn.Dispose();
    bulkCopy.Close();
    if (bulkCopy != null)
    {
        ((IDisposable)bulkCopy).Dispose();
    }                        
}
Run Code Online (Sandbox Code Playgroud)

这里更新完整的代码.

try
        {

            using (SqlConnection SQlConn = new SqlConnection(Common.SQLConnectionString))
            {


                DataTable dt1 = FillEmptyDateFields(dtDestination);

                //SqlTableCreator ObjTbl = new SqlTableCreator(SQlConn);

                //ObjTbl.DestinationTableName = DestinationTable;
                using (System.Data.SqlClient.SqlBulkCopy bulkCopy = new System.Data.SqlClient.SqlBulkCopy(SQlConn,SqlBulkCopyOptions.TableLock,null))
                {

                    //bulkCopy = new System.Data.SqlClient.SqlBulkCopy(SQlConn);
                    bulkCopy.DestinationTableName = DestinationTable;
                    bulkCopy.BulkCopyTimeout = 0;
                    bulkCopy.BatchSize = dt1.Rows.Count;
                    Logger.Log("DATATABLE FINAL :" + dt1.Rows.Count.ToString(), Logger.LogType.Info);
                    if (SQlConn.State == ConnectionState.Closed || SQlConn.State == ConnectionState.Broken)
                        SQlConn.Open();
                    bulkCopy.WriteToServer(dt1);
                    SQlConn.Close();
                    SQlConn.Dispose();
                    bulkCopy.Close();
                    if (bulkCopy != null)
                    {
                        ((IDisposable)bulkCopy).Dispose();
                    }                        
                }

            }

            dtDestination.Dispose();
            System.GC.Collect();
            dtDestination = null;
        }
        catch (Exception ex)
        {
            Logger.Log(ex, Logger.LogType.Error);
            throw ex;

        }
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 9

这里的关键问题是:dt1它是什么,它来自哪里,以及你是如何发布它的?DataTable实际上很难清理掉,坦率地说我通常不会DataTable在这里推荐一个来源.但是,如果必须使用DataTable,请确保并使用完全独立DataSet/ DataTable每次迭代,并释放旧的,以便它可以回收.

但是,使用效率更高WriteToServer(IDataReader)- 这允许您以流方式处理行.如果你在两个SQL系统之间进行复制,你甚至可以只使用ExecuteReader()一个单独的命令/连接,但是IDataReader非常简单,你可以IDataReader为大多数源编写一个基本的(或找到这样做的库,例如用于处理分隔文件的CsvReader)例如csv/tsv).