我们在 C# 中使用 SqlBulkCopy 类。在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
来源在这里。但是,如果您must use DataTable
,然后确保并使用完全独立的DataSet
/ DataTable
每次迭代,并释放旧的,以便它可以回收。
然而,更有效的方法是使用WriteToServer(IDataReader)
- 这允许您以流方式处理行。如果您要在两个 SQL 系统之间复制,您甚至可以只使用ExecuteReader()
在单独的命令/连接上,但是IDataReader
很简单,你可以写一个基本的IDataReader
对于大多数来源(或找到这样做的库,例如CSV阅读器用于处理分隔文件,例如 csv/tsv)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)