快速插入200万行SQL Server

我必须从文本文件中插入大约200万行。

而插入我必须创build一些主表。

什么是最好的和快速的方式来插入如此大的数据到SQL Server?

您可以尝试使用SqlBulkCopy类。

使您可以有效地使用其他来源的数据批量加载SQL Server表。

有一个很酷的博客文章,关于如何使用它。

  1. 我认为它更好地读取DataSet中的文本文件的数据

  2. 试用SqlBulkCopy – 从C#App批量插入SQL

    // connect to SQL using (SqlConnection connection = new SqlConnection(connString)) { // make sure to enable triggers // more on triggers in next post SqlBulkCopy bulkCopy = new SqlBulkCopy ( connection, SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.UseInternalTransaction, null ); // set the destination table name bulkCopy.DestinationTableName = this.tableName; connection.Open(); // write the data in the "dataTable" bulkCopy.WriteToServer(dataTable); connection.Close(); } // reset this.dataTable.Clear(); 

要么

在顶部做了第一步之后

  1. 从DataSet创buildXML
  2. 将XML传递给数据库并进行批量插入

你可以查看这篇文章的细节: 使用C#DataTable和SQL Server OpenXML函数批量插入数据

但它没有testing200万条logging,它会做,但会消耗机器上的内存,因为你必须加载200万条logging,并插入它。

重新为SqlBulkCopy解决scheme:

我使用StreamReader来转换和处理文本文件。 结果是我的对象列表。

我创build的CommitBatchSize DatatableList<T>和Buffer大小( CommitBatchSize )。 它将使用扩展名(第二类)将列表转换为数据表。

它工作得非常快。 在我的电脑上,我能够在不到10秒的时间内插入超过1000万条复杂的logging。

这是class级:

 using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DAL { public class BulkUploadToSql<T> { public IList<T> InternalStore { get; set; } public string TableName { get; set; } public int CommitBatchSize { get; set; }=1000; public string ConnectionString { get; set; } public void Commit() { if (InternalStore.Count>0) { DataTable dt; int numberOfPages = (InternalStore.Count / CommitBatchSize) + (InternalStore.Count % CommitBatchSize == 0 ? 0 : 1); for (int pageIndex = 0; pageIndex < numberOfPages; pageIndex++) { dt= InternalStore.Skip(pageIndex * CommitBatchSize).Take(CommitBatchSize).ToDataTable(); BulkInsert(dt); } } } public void BulkInsert(DataTable dt) { using (SqlConnection connection = new SqlConnection(ConnectionString)) { // make sure to enable triggers // more on triggers in next post SqlBulkCopy bulkCopy = new SqlBulkCopy ( connection, SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.UseInternalTransaction, null ); // set the destination table name bulkCopy.DestinationTableName = TableName; connection.Open(); // write the data in the "dataTable" bulkCopy.WriteToServer(dt); connection.Close(); } // reset //this.dataTable.Clear(); } } public static class BulkUploadToSqlHelper { public static DataTable ToDataTable<T>(this IEnumerable<T> data) { PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T)); DataTable table = new DataTable(); foreach (PropertyDescriptor prop in properties) table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType); foreach (T item in data) { DataRow row = table.NewRow(); foreach (PropertyDescriptor prop in properties) row[prop.Name] = prop.GetValue(item) ?? DBNull.Value; table.Rows.Add(row); } return table; } } 

}

下面是一个例子,当我想插入我的自定义对象List<PuckDetection>ListDetections ):

 var objBulk = new BulkUploadToSql<PuckDetection>() { InternalStore = ListDetections, TableName= "PuckDetections", CommitBatchSize=1000, ConnectionString="ENTER YOU CONNECTION STRING" }; objBulk.Commit(); 

如果需要,可以修改BulkInsert类以添加列映射。 例如,您有一个Identity Key作为第一列(假定数据表中的列名与数据库相同)

 //ADD COLUMN MAPPING foreach (DataColumn col in dt.Columns) { bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName); } 

我最近碰到了这个场景(超过700万行),并且使用sqlcmd通过powershell(在将原始数据parsing为SQL插入语句之后)以每次5,000个分段的方式获得支持(SQL无法在一个整体工作中处理700万行甚至500,000行,除非它被分解成更小的5K块,然后你可以依次运行每个5K脚本),因为我需要利用SQL Server 2012 Enterprise中的新序列命令。 我无法find一种能够快速高效地使用所述序列命令插入700万行数据的程序化方法。

其次,在插入一百万行或更多的数据时要注意的一件事是插入过程中的CPU和内存消耗(主要是内存)。 SQL将会占用这个数量级的内存/ CPU而不释放所述的进程。 不用说,如果你的服务器上没有足够的处理能力或内存,你可以在很短的时间内很容易地崩溃(我发现这很困难)。 如果你的内存消耗超过70-75%,只要重启服务器,进程将恢复正常。

我必须运行一系列的试验和错误testing,才能确定我的服务器的限制(在有限的CPU /内存资源下工作),然后才能确定最终的执行计划。 我build议你在testing环境中做同样的事情,然后把它投入生产。

我使用bcp实用程序。 (批量复制程序)我每个月加载大约150万条文本logging。 每个文本logging是800个字符宽。 在我的服务器上,大约需要30秒将150万条文本logging添加到SQL Server表中。

有关bcp的说明,请访问http://msdn.microsoft.com/en-us/library/ms162802.aspx