说来惭愧,关于批量导入数据,一直采用的是最原始的方式,一条一条插入,或者100条一块批量插入,这种方式,五十步笑百步,并没有明显的性能提升,
昨天在从别的库查询数据到DataTable内存中,然后插入另外一个库的时候,时间慢的要死,区区10W条数据,竟然要执行三分半。。。
声明一下,目标库是SQL Server。
百度了一下,SQLBulk闯入了我的视野,其实以前也了解过这个家伙,不过一直没有应用,
直接上代码。。。
public int SqlBulkInsertForSQLServer(DataTable dt, string destionTable)
{
int ires = 0;
string costtime = "";
SqlBulkCopy bulkCopy = new SqlBulkCopy(ConnectionString);
bulkCopy.DestinationTableName = destionTable;
bulkCopy.BatchSize = dt.Rows.Count;
var watch = CommonHelper.TimerStart();
if (dt != null && dt.Rows.Count != 0)
{
//插入到数据表中
bulkCopy.WriteToServer(dt);
}
bulkCopy.Close();
ires = dt.Rows.Count;
return ires;
}
注意:
1.这个地方需要注意的是DataTable列的顺序,要跟目标库的列顺序一直,包括数据库字段类型。。。
2.有的时候报类型不一致,排查的时候发现类型一致,这个时候要去确认一下是不是少加列了,导致跟目标表的字段不一致。
SQL Server库,如果目标表有一个自增列的话,会出现问题,这种情况下建议先建个临时表,将数据导入后 ,再操作临时表插入目标表。
改进后的写法:
#region sqlserver 大批量数据插入
/// <summary>
/// sqlserver 大批量数据插入
/// </summary>
/// <param name="dt"></param>
/// <param name="tablename">表名</param>
/// <param name="columns">列名</param>
public void BulkInsertForDataTable(DataTable dt, string tablename, string[] columns)
{
using (SqlConnection connection = new SqlConnection(constr_his))
{
connection.Open();
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
{
try
{
bulkCopy.DestinationTableName = tablename;//要插入的表的表明
//映射字段名 DataTable列名 ,数据库 对应的列名
foreach (string column in columns)
{
bulkCopy.ColumnMappings.Add(column, column);
}
bulkCopy.WriteToServer(dt);
}
catch (Exception ex)
{
//throw new Exception(ex.Message);
}
finally
{
// Close the SqlDataReader. The SqlBulkCopy
// object is automatically closed at the end
// of the using block.
}
}
}
}
#endregion