SQL Server批量插入数据案例详解

作者:小何同学_ 时间:2024-01-28 13:24:42 

在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数据的话,循环使用Insert不仅效率低,而且会导致SQL一系统性能问题。下面介绍SQL Server支持的两种批量数据插入方法:Bulk和表值参数(Table-Valued Parameters),高效插入数据。

新建数据库:


--Create DataBase  
create database BulkTestDB;  
go  
use BulkTestDB;  
go  
--Create Table  
Create table BulkTestTable(  
Id int primary key,  
UserName nvarchar(32),  
Pwd varchar(16))  
go

一.传统的INSERT方式

先看下传统的INSERT方式:一条一条的插入(性能消耗越来越大,速度越来越慢)


       //使用简单的Insert方法一条条插入 [慢]
       #region [ simpleInsert ]
       static void simpleInsert()
       {
           Console.WriteLine("使用简单的Insert方法一条条插入");
           Stopwatch sw = new Stopwatch();
           SqlConnection sqlconn = new SqlConnection("server=.;database=BulkTestDB;user=sa;password=123456;");
           SqlCommand sqlcmd = new SqlCommand();
           sqlcmd.CommandText = string.Format("insert into BulkTestTable(Id,UserName,Pwd)values(@p0,@p1,@p2)");
           sqlcmd.Parameters.Add("@p0", SqlDbType.Int);
           sqlcmd.Parameters.Add("@p1", SqlDbType.NVarChar);
           sqlcmd.Parameters.Add("@p2", SqlDbType.NVarChar);
           sqlcmd.CommandType = CommandType.Text;
           sqlcmd.Connection = sqlconn;
           sqlconn.Open();
           try
           {
               //循环插入1000条数据,每次插入100条,插入10次。  
               for (int multiply = 0; multiply < 10; multiply++)
               {
                   for (int count = multiply * 100; count < (multiply + 1) * 100; count++)
                   {

sqlcmd.Parameters["@p0"].Value = count;
                       sqlcmd.Parameters["@p1"].Value = string.Format("User-{0}", count * multiply);
                       sqlcmd.Parameters["@p2"].Value = string.Format("Pwd-{0}", count * multiply);
                       sw.Start();
                       sqlcmd.ExecuteNonQuery();
                       sw.Stop();
                   }
                   //每插入10万条数据后,显示此次插入所用时间  
                   Console.WriteLine(string.Format("Elapsed Time is {0} Milliseconds", sw.ElapsedMilliseconds));
               }
               Console.ReadKey();
           }
           catch (Exception ex)
           {
               Console.WriteLine(ex.Message);
           }
       }
       #endregion

循环插入1000条数据,每次插入100条,插入10次,效率是越来越慢。

SQL Server批量插入数据案例详解

二.较快速的Bulk插入方式:

使用使用Bulk插入[ 较快 ]


       //使用Bulk插入的情况 [ 较快 ]
       #region [ 使用Bulk插入的情况 ]
       static void BulkToDB(DataTable dt)
       {
           Stopwatch sw = new Stopwatch();
           SqlConnection sqlconn = new SqlConnection("server=.;database=BulkTestDB;user=sa;password=123456;");
           SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlconn);
           bulkCopy.DestinationTableName = "BulkTestTable";
           bulkCopy.BatchSize = dt.Rows.Count;
           try
           {
               sqlconn.Open();
               if (dt != null && dt.Rows.Count != 0)
               {
                   bulkCopy.WriteToServer(dt);
               }
           }
           catch (Exception ex)
           {
               Console.WriteLine(ex.Message);
           }
           finally
           {
               sqlconn.Close();
               if (bulkCopy != null)
               {
                   bulkCopy.Close();
               }
           }
       }
       static DataTable GetTableSchema()
       {
           DataTable dt = new DataTable();
           dt.Columns.AddRange(new DataColumn[] {
               new DataColumn("Id",typeof(int)),
               new DataColumn("UserName",typeof(string)),
               new DataColumn("Pwd",typeof(string))
           });
           return dt;
       }
       static void BulkInsert()
       {
           Console.WriteLine("使用简单的Bulk插入的情况");
           Stopwatch sw = new Stopwatch();
           for (int multiply = 0; multiply < 10; multiply++)
           {
               DataTable dt = GetTableSchema();
               for (int count = multiply * 100; count < (multiply + 1) * 100; count++)
               {
                   DataRow r = dt.NewRow();
                   r[0] = count;
                   r[1] = string.Format("User-{0}", count * multiply);
                   r[2] = string.Format("Pwd-{0}", count * multiply);
                   dt.Rows.Add(r);
               }
               sw.Start();
               BulkToDB(dt);
               sw.Stop();
               Console.WriteLine(string.Format("Elapsed Time is {0} Milliseconds", sw.ElapsedMilliseconds));
           }
       }
       #endregion

循环插入1000条数据,每次插入100条,插入10次,效率快了很多。

SQL Server批量插入数据案例详解

三.使用简称TVPs插入数据

打开sqlserrver,执行以下脚本:


--Create Table Valued  
CREATE TYPE BulkUdt AS TABLE  
 (Id int,  
  UserName nvarchar(32),  
  Pwd varchar(16))

SQL Server批量插入数据案例详解

成功后在数据库中发现多了BulkUdt的缓存表。

使用简称TVPs插入数据


       //使用简称TVPs插入数据 [最快]
       #region [ 使用简称TVPs插入数据 ]
       static void TbaleValuedToDB(DataTable dt)
       {
           Stopwatch sw = new Stopwatch();
           SqlConnection sqlconn = new SqlConnection("server=.;database=BulkTestDB;user=sa;password=123456;");
           const string TSqlStatement =
                 "insert into BulkTestTable (Id,UserName,Pwd)" +
                 " SELECT nc.Id, nc.UserName,nc.Pwd" +
                 " FROM @NewBulkTestTvp AS nc";
           SqlCommand cmd = new SqlCommand(TSqlStatement, sqlconn);
           SqlParameter catParam = cmd.Parameters.AddWithValue("@NewBulkTestTvp", dt);
           catParam.SqlDbType = SqlDbType.Structured;
           catParam.TypeName = "dbo.BulkUdt";
           try
           {
               sqlconn.Open();
               if (dt != null && dt.Rows.Count != 0)
               {
                   cmd.ExecuteNonQuery();
               }
           }
           catch (Exception ex)
           {
               Console.WriteLine("error>" + ex.Message);
           }
           finally
           {
               sqlconn.Close();
           }
       }
       static void TVPsInsert()
       {
           Console.WriteLine("使用简称TVPs插入数据");
           Stopwatch sw = new Stopwatch();
           for (int multiply = 0; multiply < 10; multiply++)
           {
               DataTable dt = GetTableSchema();
               for (int count = multiply * 100; count < (multiply + 1) * 100; count++)
               {
                   DataRow r = dt.NewRow();
                   r[0] = count;
                   r[1] = string.Format("User-{0}", count * multiply);
                   r[2] = string.Format("Pwd-{0}", count * multiply);
                   dt.Rows.Add(r);
               }
               sw.Start();
               TbaleValuedToDB(dt);
               sw.Stop();
               Console.WriteLine(string.Format("Elapsed Time is {0} Milliseconds", sw.ElapsedMilliseconds));
           }
           Console.ReadLine();  
       }
       #endregion

SQL Server批量插入数据案例详解

循环插入1000条数据,每次插入100条,插入10次,效率是越来越慢,后面测试,将每次插入的数据量增大,会更大的体现TPVS插入的效率。

来源:https://blog.csdn.net/heyangyi_19940703/article/details/51981731

标签:sql,server,插入
0
投稿

猜你喜欢

  • 手把手教你从PyCharm安装到激活(最新激活码),亲测有效可激活至2089年

    2021-06-16 19:53:55
  • Laravel实现队列的示例代码

    2023-05-28 04:39:21
  • Spring数据库事务的实现机制讲解

    2024-01-19 11:32:10
  • Python爬虫必备技巧详细总结

    2022-10-02 12:47:44
  • Python编程之多态用法实例详解

    2022-08-01 23:42:31
  • Python实现向好友发送微信消息

    2021-11-11 18:33:02
  • Python 的可变和不可变对象详情

    2021-11-24 22:28:33
  • Python通过队列实现进程间通信详情

    2023-07-24 17:49:44
  • Python整型运算之布尔型、标准整型、长整型操作示例

    2021-01-28 06:39:15
  • Keras使用ImageNet上预训练的模型方式

    2021-03-01 10:08:51
  • MySql 随机取N条数据

    2009-03-17 12:46:00
  • Python获取当前脚本文件夹(Script)的绝对路径方法代码

    2021-05-27 09:57:52
  • vue 循环动态设置ref并获取$refs方式

    2023-07-02 17:00:18
  • MySQL数据库性能优化的八大“妙手”

    2009-07-30 08:58:00
  • laravel中的一些简单实用功能

    2024-05-13 09:51:57
  • python time时间库详解

    2023-10-09 03:20:57
  • python性能测试手机号验证码登录压测示例详解

    2021-06-05 13:21:25
  • Python使用QQ邮箱发送Email的方法实例

    2021-03-25 11:33:57
  • 一文让你快速了解JavaScript栈

    2024-04-29 13:22:04
  • python获取mp3文件信息的方法

    2023-12-18 19:49:11
  • asp之家 网络编程 m.aspxhome.com