Pertanyaan Masalah memori copy massal Sql


Kami menggunakan kelas SqlBulk Copy di C #. Untuk memasukkan data Bulk dalam sql. Kami memiliki meja dengan 10 juta catatan di dalamnya.

Kami memasukkan data dalam batch 10.000 dalam satu lingkaran

Kami menghadapi masalah memori fisik. Memori meningkat dan tidak berkurang.

Di bawah ini adalah kode kami. Bagaimana kita dapat melepaskan memori ketika sql bulk copy digunakan atau apakah ada cara lain untuk melakukan insert massal.

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

Di sini memperbarui kode lengkap.

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;

        }

4
2017-10-10 12:16


asal


Jawaban:


Pertanyaan kuncinya di sini adalah: apa adanya dt1, dari mana asalnya, dan bagaimana Anda melepaskannya? DataTable sebenarnya cukup sulit untuk dibersihkan, dan terus terang saya biasanya tidak akan merekomendasikan DataTable sumber di sini. Namun, jika Anda harus menggunakan DataTable, kemudian pastikan dan gunakan yang benar-benar terpisah DataSet / DataTable per iterasi, dan melepaskan yang lama sehingga dapat didaur ulang.

Lebih efisien, bagaimanapun, adalah untuk digunakan WriteToServer(IDataReader) - ini memungkinkan Anda untuk menangani baris dalam mode streaming. Jika Anda menyalin antara dua sistem SQL, Anda bahkan bisa menggunakannya ExecuteReader() pada perintah / koneksi terpisah, tetapi IDataReader sangat sederhana, dan Anda dapat menulis dasar IDataReader untuk sebagian besar sumber (atau cari pustaka yang melakukannya, misalnya CsvReader untuk menangani file yang dibatasi seperti csv / tsv).


9
2017-10-10 12:24



Saya kira masalahnya adalah dengan baris ini:

bulkCopy.BatchSize = dt1.Rows.Count; 

Properti BatchSize menentukan berapa banyak baris yang disisipkan dalam satu transaksi internal. Ukuran baris di sini berpotensi tidak terbatas.

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

Coba atur ke angka kecil dan tetap harus menyelesaikan masalah:

bulkCopy.BatchSize = 1000;

Terserah Anda untuk memutuskan ukuran batch yang optimal di sini.


1
2017-10-10 12:27