簡體   English   中英

Sql批量復制內存問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM