SqlBulkCopy像糖蜜一样慢

我正在寻找通过c#加载批量数据的最快方法。 我有这个脚本可以完成工作但速度很慢。 我读过SqlBulkCopy最快的证词。
1000记录2.5秒。 文件包含接近5000条记录到250k的任何内容有哪些可以减慢它的速度?

表格定义:

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] 

这是代码

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

您对该表有任何索引,触发器或约束吗?

这将导致插入速度减慢 – 特别是聚集索引会受到伤害。 在爆破您正在进行的数据量时,最好先删除索引,然后再重新应用它们。

关于它的一篇好文章是: 在SQL Server中大量插入大量数据的最快方法是什么(C#客户端)

如果您有大量数据,将batchsize设置为相当大的数量可能会有所帮助:

 bcp.BatchSize = 10000; 

可以减慢批量复制的事情: – 表上的全文本索引 – 插入上的触发器 – 按键 – 键约束

我注意到,尝试冲洗大型数据集最初要快得多,但随着时间的推移会大幅减慢。 我发现使用缓冲方法适度增加性能,在同一连接下一次只为几千条记录提供批量复制。 它似乎随着时间的推移保持每批次的交易时间,这(随着时间的推移)提高了性能。 在我的解决方案中,我注意到,在这种方法将相同类型的约7,500,000条记录保存到同一个数据库所需的时间内,未缓冲的相同方法将节省大约5,000,000条记录。 希望这有助于某人。

 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 } } 

我在这里提到的IDataReader实现如何实现IDataReader? 也许会帮助你。 我用它与SqlBulkCopy如下:

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