[英]Sql bulk copy memory issue
我們在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;
由您決定此處的最佳批量大小。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.