一致对于大批量数据插入,效率有疑问。今天我就以以下几种方式进行数据插入进行比较。

  •  前景提示

首先写了一个随机产生汉子的帮助类,以参数不同的数据(代码如下)。 

  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