Sql批量复制内存问题

我们在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(); } } 

这里更新完整的代码。

 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; } 

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

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

我想这个问题出在这一行:

 bulkCopy.BatchSize = dt1.Rows.Count; 

BatchSize属性确定在单个内部事务中插入的行数。 这里的行大小可能是无限的。

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.batchsize.aspx

尝试将其设置为小而固定的数字应该解决问题:

 bulkCopy.BatchSize = 1000; 

由您决定此处的最佳批量大小。