SQLServer中批量插入数据方式的性能对比(2)

发表于:2012-07-20来源:博客园作者:Kevin点击数: 标签:SQLServer
long TVPInsertRunTime = TVPInsert(); Console.WriteLine(string.Format(使用表值方式(TVP)插入{1}条数据所用的时间是{0}毫秒, TVPInsertRunTime, count)); } /// /// 普通调用存储过程插

  long TVPInsertRunTime = TVPInsert();

  Console.WriteLine(string.Format("使用表值方式(TVP)插入{1}条数据所用的时间是{0}毫秒", TVPInsertRunTime, count));

  }

  ///

  /// 普通调用存储过程插入数据

  ///

  ///

  private static long CommonInsert()

  {

  Stopwatch stopwatch = new Stopwatch();

  stopwatch.Start();

  string passportKey;

  for (int i = 0; i < count; i++)

  {

  passportKey = Guid.NewGuid().ToString();

  SqlParameter[] sqlParameter = { new SqlParameter("@passport", passportKey) };

  SqlHelper.ExecuteNonQuery(connectionString, CommandType.StoredProcedure, "CreatePassport", sqlParameter);

  }

  stopwatch.Stop();

  return stopwatch.ElapsedMilliseconds;

  }

  ///

  /// 使用SqlBulkCopy方式插入数据

  ///

  ///

  ///

  private static long SqlBulkCopyInsert()

  {

  Stopwatch stopwatch = new Stopwatch();

  stopwatch.Start();

  DataTable dataTable = GetTableSchema();

  string passportKey;

  for (int i = 0; i < count; i++)

  {

  passportKey = Guid.NewGuid().ToString();

  DataRow dataRow = dataTable.NewRow();

  dataRow[0] = passportKey;

  dataTable.Rows.Add(dataRow);

  }

  SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(connectionString);

  sqlBulkCopy.DestinationTableName = "Passport";

  sqlBulkCopy.BatchSize = dataTable.Rows.Count;

  SqlConnection sqlConnection = new SqlConnection(connectionString);

  sqlConnection.Open();

  if (dataTable!=null && dataTable.Rows.Count!=0)

  {

  sqlBulkCopy.WriteToServer(dataTable);

  }

  sqlBulkCopy.Close();

  sqlConnection.Close();

  stopwatch.Stop();

  return stopwatch.ElapsedMilliseconds;

  }

  private static long TVPInsert()

  {

  Stopwatch stopwatch = new Stopwatch();

  stopwatch.Start();

  DataTable dataTable = GetTableSchema();

  string passportKey;

  for (int i = 0; i < count; i++)

  {

  passportKey = Guid.NewGuid().ToString();

  DataRow dataRow = dataTable.NewRow();

  dataRow[0] = passportKey;

  dataTable.Rows.Add(dataRow);

  }

  SqlParameter[] sqlParameter = { new SqlParameter("@TVP", dataTable) };

  SqlHelper.ExecuteNonQuery(connectionString, CommandType.StoredProcedure, "CreatePassportWithTVP", sqlParameter);

  stopwatch.Stop();

  return stopwatch.ElapsedMilliseconds;

  }

  private static DataTable GetTableSchema()

  {

  DataTable dataTable = new DataTable();

  dataTable.Columns.AddRange(new DataColumn[] { new DataColumn("PassportKey") });

  return dataTable;

  }

  }

  }

  比较神秘的代码其实就下面这两行,该代码是将一个dataTable做为参数传给了我们的存储过程。简单吧。

  SqlParameter[] sqlParameter = { new SqlParameter("@TVP", dataTable) };

  SqlHelper.ExecuteNonQuery(connectionString, CommandType.StoredProcedure, "CreatePassportWithTVP", sqlParameter);

  5.测试并记录测试结果

第一组测试,插入记录数1000
第二组测试,插入记录数10000
第三组测试,插入记录数1000000

  通过以上测试方案,不难发现,技术方案二的优势还是蛮高的。无论是从通用性还是从性能上考虑,都应该是

  优先被选择的,还有一点,它的技术复杂度要比技术方案三要简单一些,

  设想我们把所有表都创建一遍表值类型,工作量还是有的。因此,我依然坚持我开始时的决定,

  向公司推荐使用第二种技术方案。

  写到此,本文就算完了,但是对新技术的钻研仍然还在不断继续。要做的东西还是挺多的。

原文转自:http://www.ltesting.net