一致对于大批量数据插入,效率有疑问。今天我就以以下几种方式进行数据插入进行比较。
- 前景提示
首先写了一个随机产生汉子的帮助类,以参数不同的数据(代码如下)。
public class Help { #region 根据长度随机生成汉字 public static string RandomStr(int length) { StringBuilder stringBuilder = new StringBuilder(); int area = 16; int site = 1; for (int i = 0; i < length; i++) { Random random = new Random(Encoding.Default.GetBytes(Guid.NewGuid().ToString())[0]); area = random.Next(16, 55) + 0xa0; site = random.Next(55, 88) + 0xa0; stringBuilder.Append(Encoding.GetEncoding("GB2312").GetString(new byte[] { (byte)area, (byte)site })); } return stringBuilder.ToString(); } #endregion }
建了一张数据表(Student),表结构如下
- 插入姿势
一、SqlDataAdapter插入datatable
public class SelfDataTable { public static decimal Insert(SqlConnection sqlConnection,int count) { var dataSet = new DataSet(); var sqlDataAdapter = new SqlDataAdapter { SelectCommand = new SqlCommand("select * from Student", sqlConnection) }; sqlDataAdapter.Fill(dataSet); var scb = new SqlCommandBuilder(sqlDataAdapter); if (sqlConnection.State == ConnectionState.Closed) { sqlConnection.Open(); } dataSet.Clear(); for (int i = 0; i < count; i++) { DataRow dr = dataSet.Tables[0].NewRow(); dr["Id"] = Guid.NewGuid(); dr["Name"] = Help.RandomStr(5); dr["Address"] = Help.RandomStr(50); dataSet.Tables[0].Rows.Add(dr); } var stopwatch = new Stopwatch(); stopwatch.Start(); sqlDataAdapter.Update(dataSet); stopwatch.Stop(); sqlConnection.Close(); return stopwatch.ElapsedMilliseconds; } }
二、SqlCommand执行sql语句插入
public class SelfInsertSql { public static decimal Insert(SqlConnection sqlConnection,int count) { var insertSql = new StringBuilder(); for (int i = 0; i < count; i++) { var id = Guid.NewGuid(); var name = Help.RandomStr(5);//Help.RandomStr(nameLength); var address = Help.RandomStr(50); ; insertSql.Append(" Insert Into Student ( Id,Name,Address ) Values"); insertSql.Append(string.Format(" ('{0}','{1}','{2}') ", id,name, address)); } if (sqlConnection.State == ConnectionState.Closed) { sqlConnection.Open(); } var sqlCommand = new SqlCommand(insertSql.ToString(), sqlConnection) { CommandTimeout = int.MaxValue }; var stopwatch = new Stopwatch(); stopwatch.Start(); sqlCommand.ExecuteNonQuery(); stopwatch.Stop(); sqlConnection.Close(); return stopwatch.ElapsedMilliseconds; } }
三、SqlBulkCopy
public class SelfSqlBulkCopy { public static decimal Insert(SqlConnection sqlConnection,int count) { var dataSet = new DataSet(); var sqlDataAdapter = new SqlDataAdapter(); sqlDataAdapter.SelectCommand = new SqlCommand("select * from Student", sqlConnection); var scb = new SqlCommandBuilder(sqlDataAdapter); if (sqlConnection.State == ConnectionState.Closed) { sqlConnection.Open(); } sqlDataAdapter.Fill(dataSet); dataSet.Clear(); for (int i = 0; i < count; i++) { DataRow dr = dataSet.Tables[0].NewRow(); dr["Id"] = Guid.NewGuid(); dr["Name"] = Help.RandomStr(5); dr["Address"] = Help.RandomStr(50); dataSet.Tables[0].Rows.Add(dr); } var sqlBulkCopy = new SqlBulkCopy(@"Data Source=.\sql2012;Initial Catalog=LegionData;Integrated Security=False;User Id=sa;Password=1qaz~xsw2") { DestinationTableName = "Student", BatchSize = dataSet.Tables[0].Rows.Count }; if (sqlConnection.State == ConnectionState.Closed) { sqlConnection.Open(); } var stopwatch = new Stopwatch(); stopwatch.Start(); sqlBulkCopy.WriteToServer(dataSet.Tables[0]); stopwatch.Stop(); sqlBulkCopy.Close(); sqlConnection.Close(); return stopwatch.ElapsedMilliseconds; } }
四、通过EF进行数据插入
public class SelfEf { public static decimal Insert(SelfContext selfContext,int count) { var students = new List<Student>(); for (int i = 0; i < count; i++) { var student = new Student(); students.Add(student); student.Id = Guid.NewGuid(); student.Name = Help.RandomStr(5); student.Address = Help.RandomStr(50); } selfContext.Student.AddRange(students); var stopwatch = new Stopwatch(); stopwatch.Start(); selfContext.SaveChanges(); stopwatch.Stop(); return stopwatch.ElapsedMilliseconds ; } }
-
- 执行结果
从以下结果可以得出
1(条) | 1000条 | 10000条 | 100000条 | |
SqlDataAdapter | 76ms | 9572ms | 91713ms | 904910ms |
SqlCommand | 12ms | 225ms | 2628ms | 54072ms |
SqlBulkCopy | 10ms | 30ms | 173ms | 2103ms |
EF | 245ms | 14720ms | 147766ms | 1450658ms |