2010-04-22 16 views
5

Toplu verileri C# üzerinden yüklemek için en hızlı yolu arıyorum. İşi yapan ama yavaş olan bu betiğe sahibim. SqlBulkCopy'nin en hızlı olduğu ifadelerini okudum.
1000 kayıt 2,5 saniye. dosyalar 250k'ye kadar olan kayıtların bulunduğu herhangi bir yerde 250k arasındadır. Yavaşlatabilecek bazı şeyler nelerdir?SqlBulkCopy pekmezi yavaşlatıyor

Tablo Def: Burada

CREATE TABLE [dbo].[tempDispositions](
    [QuotaGroup] [varchar](100) NULL, 
    [Country] [varchar](50) NULL, 
    [ServiceGroup] [varchar](50) NULL, 
    [Language] [varchar](50) NULL, 
    [ContactChannel] [varchar](10) NULL, 
    [TrackingID] [varchar](20) NULL, 
    [CaseClosedDate] [varchar](25) NULL, 
    [MSFTRep] [varchar](50) NULL, 
    [CustEmail] [varchar](100) NULL, 
    [CustPhone] [varchar](100) NULL, 
    [CustomerName] [nvarchar](100) NULL, 
    [ProductFamily] [varchar](35) NULL, 
    [ProductSubType] [varchar](255) NULL, 
    [CandidateReceivedDate] [varchar](25) NULL, 
    [SurveyMode] [varchar](1) NULL, 
    [SurveyWaveStartDate] [varchar](25) NULL, 
    [SurveyInvitationDate] [varchar](25) NULL, 
    [SurveyReminderDate] [varchar](25) NULL, 
    [SurveyCompleteDate] [varchar](25) NULL, 
    [OptOutDate] [varchar](25) NULL, 
    [SurveyWaveEndDate] [varchar](25) NULL, 
    [DispositionCode] [varchar](5) NULL, 
    [SurveyName] [varchar](20) NULL, 
    [SurveyVendor] [varchar](20) NULL, 
    [BusinessUnitName] [varchar](25) NULL, 
    [UploadId] [int] NULL, 
    [LineNumber] [int] NULL, 
    [BusinessUnitSubgroup] [varchar](25) NULL, 
    [FileDate] [datetime] NULL 
) ON [PRIMARY] 

ve

private void BulkLoadContent(DataTable dt) 
    { 
     OnMessage("Bulk loading records to temp table"); 
     OnSubMessage("Bulk Load Started"); 
     using (SqlBulkCopy bcp = new SqlBulkCopy(conn)) 
     { 
      bcp.DestinationTableName = "dbo.tempDispositions"; 
      bcp.BulkCopyTimeout = 0; 
      foreach (DataColumn dc in dt.Columns) 
      { 
       bcp.ColumnMappings.Add(dc.ColumnName, dc.ColumnName); 
      } 
      bcp.NotifyAfter = 2000; 
      bcp.SqlRowsCopied += new SqlRowsCopiedEventHandler(bcp_SqlRowsCopied); 
      bcp.WriteToServer(dt); 
      bcp.Close(); 
     } 
    } 
+1

Yavaş? Kaç kayıt var? Başka hangi yaklaşımları denediniz? Bu "yavaş", "biraz daha iyi git, biraz kahve al" ya da "Elinden daha hızlı yazabilirim" gibi mi? – GalacticCowboy

+0

Yavaşça "Biraz kahve alsam iyi olur" 1000 kayıt 2,5 saniye. dosyalar 250k'ye kadar –

+0

için 5000 kaydın herhangi bir yerini içerir. db'nizin bir 'LOAD DATA INFILE' işlevi var mı? – dnagirl

cevap

7

Herhangi endeksler var mı kodu olduğunu masaya tetikleyen veya kısıtlamalar? uç üzerindeki yavaşlamalar neden olur

- özellikle bir kümelenmiş dizin zarar vereceğini. Yapmakta olduğunuz veri miktarını patlatırken, önce dizinleri bırakmak ve sonradan yeniden uygulamak en iyisidir.

bu konuda iyi bir mesaj geldi: Toplu kopya yavaşlatabilir What's the fastest way to bulk insert a lot of data in SQL Server (C# client)

1

şeyler: masanın Ekle üzerinde -Triggers üzerinde -Tam metin endeksleri -Dış Anahtar kısıtlamalar

3

Eğer büyük miktarda veri varsa makul sayıda BatchSize ayar yardımcı olabilir:

bcp.BatchSize = 10000; 
0

Ben SUG IDataReader uygulama Burada How to implement IDataReader? belki de size yardımcı olur.

using (MyFileDataReader reader = new MyFileDataReader(@"C:\myfile.txt")) 
{ 
     SqlBulkCopy bulkCopy = new SqlBulkCopy(connection); 
     bulkCopy.DestinationTableName = "[my_table]"; 
     bulkCopy.BatchSize = 10000; 

     bulkCopy.WriteToServer(reader); 

     bulkCopy.Close(); 

} 
1

Ben büyük veri kümelerini temizlemek için çalışıyor çok daha hızlı başlangıçta olduğunu fark ettik, ancak zamanla aşağı ölçüde yavaşlatır şu şekildedir: SqlBulkCopy ile kullandım. Tamponlu bir yaklaşım kullanarak performansta küçük bir artış gördüm, aynı bağlantı altında bir seferde sadece birkaç bin kayıt toplu kopyalama. Toplu iş başına işlem süresinin zamanla azalmasını sağlar, bu da (zamanla) performansı artırır. Çözümümde, aynı yöntemin arabelleğe alınmadığının, aynı DB'ye aynı türden yaklaşık 7.500.000 kayıt saklamak için bu yöntemi kullandığı sırada 5.000.000 kayıt saklayacağını kaydettim. Umut, bu birisine yardımcı olur. Ne kıyasla

public void flush_DataTable(DataTable dt, string tableName)//my incoming DTs have a million or so each and slow down over time to nothing. This helps. 
    { int bufferSize = 10000; 
     int bufferHigh = bufferSize; 
     int lowBuffer = 0; 
     if (dt.Rows.Count >= bufferSize) 
     { using (SqlConnection conn = getConn()) 
      { conn.Open(); 
       while (bufferHigh < dt.Rows.Count) 
       { 
        using (SqlBulkCopy s = new SqlBulkCopy(conn)) 
        { s.BulkCopyTimeout = 900; 
         s.DestinationTableName = tableName; 
         s.BatchSize = bufferSize; 

         s.EnableStreaming = true; 
         foreach (var column in dt.Columns) 
          s.ColumnMappings.Add(column.ToString(), column.ToString()); 
         DataTable bufferedTable = dt.Clone(); 
         for (int bu = lowBuffer; bu < bufferHigh; bu++) 
         { 
          bufferedTable.ImportRow(dt.Rows[bu]); 
         } 
         s.WriteToServer(bufferedTable); 
         if (bufferHigh == dt.Rows.Count) 
         { 
          break; 
         } 
         lowBuffer = bufferHigh; 
         bufferHigh += bufferSize; 

         if (bufferHigh > dt.Rows.Count) 
         { 
          bufferHigh = dt.Rows.Count; 
         } 
        } 
       } 
       conn.Close(); 
      } 
     } 
     else 
     { 
      flushDataTable(dt, tableName);//perofrm a non-buffered flush (could just as easily flush the buffer here bu I already had the other method 
     } 
    } 
+0

Belki bir Paralel kullanarak işleri hızlandırabilirsiniz. Tablo kopyası için ve/veya s.WriteToServerAsync'yi kullanarak 2-3 paralel eklemeye izin vererek iş parçacığından faydalanabilirsiniz. Ayrıca, kullanım (lar) ın içindeki döngü mantığını (WHILE) ve sütun eşlemesinden sonra her şeyi aynı SQLBulkCopy örneğinin altında gerçekleşmesini deneyebilirsiniz - zaman içinde performanstaki% 50'lik artışla yeterince mutlu oldum. Bu diğer hilelerin. YMMV –

+1

Ayrıca - bir tablo boş olduğunda bu daha yavaştır - tablo dolduğunda performans kazanımları görünür. Birkaç milyon kayıt için bunun çok fazla kullanılması gerektiğinden şüphe duyuyorum. Ama yüz milyonlarca yıldır, bana bir sürü zaman kazandırdı. –

İlgili konular