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

运行下面的脚本,建立测试数据库和表值参数。

[c-sharp] view plaincopy
  1. --Create DataBase
  2. create database BulkTestDB;
  3. go
  4. use BulkTestDB;
  5. go
  6. --Create Table
  7. Create table BulkTestTable(
  8. Id int primary key,
  9. UserName nvarchar(32),
  10. Pwd varchar(16))
  11. go
  12. --Create Table Valued
  13. CREATE TYPE BulkUdt AS TABLE
  14. (Id int,
  15. UserName nvarchar(32),
  16. Pwd varchar(16))

下面我们使用最简单的Insert语句来插入100万条数据,代码如下:

[c-sharp] view plaincopy
  1. Stopwatch sw = new Stopwatch();
  2. SqlConnection sqlConn = new SqlConnection(
  3. ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString);//连接数据库
  4. SqlCommand sqlComm = new SqlCommand();
  5. sqlComm.CommandText = string.Format("insert into BulkTestTable(Id,UserName,Pwd)values(@p0,@p1,@p2)");//参数化SQL
  6. sqlComm.Parameters.Add("@p0", SqlDbType.Int);
  7. sqlComm.Parameters.Add("@p1", SqlDbType.NVarChar);
  8. sqlComm.Parameters.Add("@p2", SqlDbType.VarChar);
  9. sqlComm.CommandType = CommandType.Text;
  10. sqlComm.Connection = sqlConn;
  11. sqlConn.Open();
  12. try
  13. {
  14. //循环插入100万条数据,每次插入10万条,插入10次。
  15. for (int multiply = 0; multiply < 10; multiply++)
  16. {
  17. for (int count = multiply * 100000; count < (multiply + 1) * 100000; count++)
  18. {
  19. sqlComm.Parameters["@p0"].Value = count;
  20. sqlComm.Parameters["@p1"].Value = string.Format("User-{0}", count * multiply);
  21. sqlComm.Parameters["@p2"].Value = string.Format("Pwd-{0}", count * multiply);
  22. sw.Start();
  23. sqlComm.ExecuteNonQuery();
  24. sw.Stop();
  25. }
  26. //每插入10万条数据后,显示此次插入所用时间
  27. Console.WriteLine(string.Format("Elapsed Time is {0} Milliseconds", sw.ElapsedMilliseconds));
  28. }
  29. }
  30. catch (Exception ex)
  31. {
  32. throw ex;
  33. }
  34. finally
  35. {
  36. sqlConn.Close();
  37. }
  38. Console.ReadLine();

耗时图如下:

由于运行过慢,才插入10万条就耗时72390 milliseconds,所以我就手动强行停止了。

下面看一下使用Bulk插入的情况:

bulk方法主要思想是通过在客户端把数据都缓存在Table中,然后利用SqlBulkCopy一次性把Table中的数据插入到数据库

代码如下:

[c-sharp] view plaincopy
  1. public static void BulkToDB(DataTable dt)
  2. {
  3. SqlConnection sqlConn = new SqlConnection(
  4. ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString);
  5. SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConn);
  6. bulkCopy.DestinationTableName = "BulkTestTable";
  7. bulkCopy.BatchSize = dt.Rows.Count;
  8. try
  9. {
  10. sqlConn.Open();
  11. if (dt != null && dt.Rows.Count != 0)
  12. bulkCopy.WriteToServer(dt);
  13. }
  14. catch (Exception ex)
  15. {
  16. throw ex;
  17. }
  18. finally
  19. {
  20. sqlConn.Close();
  21. if (bulkCopy != null)
  22. bulkCopy.Close();
  23. }
  24. }
  25. public static DataTable GetTableSchema()
  26. {
  27. DataTable dt = new DataTable();
  28. dt.Columns.AddRange(new DataColumn[]{
  29. new DataColumn("Id",typeof(int)),
  30. new DataColumn("UserName",typeof(string)),
  31. new DataColumn("Pwd",typeof(string))});
  32. return dt;
  33. }
  34. static void Main(string[] args)
  35. {
  36. Stopwatch sw = new Stopwatch();
  37. for (int multiply = 0; multiply < 10; multiply++)
  38. {
  39. DataTable dt = Bulk.GetTableSchema();
  40. for (int count = multiply * 100000; count < (multiply + 1) * 100000; count++)
  41. {
  42. DataRow r = dt.NewRow();
  43. r[0] = count;
  44. r[1] = string.Format("User-{0}", count * multiply);
  45. r[2] = string.Format("Pwd-{0}", count * multiply);
  46. dt.Rows.Add(r);
  47. }
  48. sw.Start();
  49. Bulk.BulkToDB(dt);
  50. sw.Stop();
  51. Console.WriteLine(string.Format("Elapsed Time is {0} Milliseconds", sw.ElapsedMilliseconds));
  52. }
  53. Console.ReadLine();
  54. }

耗时图如下:

可见,使用Bulk后,效率和性能明显上升。使用Insert插入10万数据耗时72390,而现在使用Bulk插入100万数据才耗时17583。

最后再看看使用表值参数的效率,会另你大为惊讶的。

表值参数是SQL Server 2008新特性,简称TVPs。对于表值参数不熟悉的朋友,可以参考最新的book online,我也会另外写一篇关于表值参数的博客,不过此次不对表值参数的概念做过多的介绍。言归正传,看代码:

[c-sharp] view plaincopy
  1. public static void TableValuedToDB(DataTable dt)
  2. {
  3. SqlConnection sqlConn = new SqlConnection(
  4. ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString);
  5. const string TSqlStatement =
  6. "insert into BulkTestTable (Id,UserName,Pwd)" +
  7. " SELECT nc.Id, nc.UserName,nc.Pwd" +
  8. " FROM @NewBulkTestTvp AS nc";
  9. SqlCommand cmd = new SqlCommand(TSqlStatement, sqlConn);
  10. SqlParameter catParam = cmd.Parameters.AddWithValue("@NewBulkTestTvp", dt);
  11. catParam.SqlDbType = SqlDbType.Structured;
  12. //表值参数的名字叫BulkUdt,在上面的建立测试环境的SQL中有。
  13. catParam.TypeName = "dbo.BulkUdt";
  14. try
  15. {
  16. sqlConn.Open();
  17. if (dt != null && dt.Rows.Count != 0)
  18. {
  19. cmd.ExecuteNonQuery();
  20. }
  21. }
  22. catch (Exception ex)
  23. {
  24. throw ex;
  25. }
  26. finally
  27. {
  28. sqlConn.Close();
  29. }
  30. }
  31. public static DataTable GetTableSchema()
  32. {
  33. DataTable dt = new DataTable();
  34. dt.Columns.AddRange(new DataColumn[]{
  35. new DataColumn("Id",typeof(int)),
  36. new DataColumn("UserName",typeof(string)),
  37. new DataColumn("Pwd",typeof(string))});
  38. return dt;
  39. }
  40. static void Main(string[] args)
  41. {
  42. Stopwatch sw = new Stopwatch();
  43. for (int multiply = 0; multiply < 10; multiply++)
  44. {
  45. DataTable dt = TableValued.GetTableSchema();
  46. for (int count = multiply * 100000; count < (multiply + 1) * 100000; count++)
  47. {
  48. DataRow r = dt.NewRow();
  49. r[0] = count;
  50. r[1] = string.Format("User-{0}", count * multiply);
  51. r[2] = string.Format("Pwd-{0}", count * multiply);
  52. dt.Rows.Add(r);
  53. }
  54. sw.Start();
  55. TableValued.TableValuedToDB(dt);
  56. sw.Stop();
  57. Console.WriteLine(string.Format("Elapsed Time is {0} Milliseconds", sw.ElapsedMilliseconds));
  58. }
  59. Console.ReadLine();
  60. }

耗时图如下:

比Bulk还快5秒。

转载于:https://www.cnblogs.com/EasyLive2006/p/7635805.html

SQL Server 批量插入数据的两种方法 - 转相关推荐

  1. SQL Server 批量插入数据的两种方法(转)

    原文:http://blog.csdn.net/tjvictor/article/details/4360030 在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数 ...

  2. 【转载】SQL Server 批量插入数据的两种方法

    在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数据的话,循环使用Insert不仅效率低,而且会导致SQL一系统性能问题.下面介绍SQL Server支持的两种批量 ...

  3. SQLServer 批量插入数据的两种方法

    SQLServer 批量插入数据的两种方法- 发布:dxy 字体:[增加 减小] 类型:转载 在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数据的话,循环使用In ...

  4. SQL Server 批量插入数据方案 SqlBulkCopy 的简单封装,让批量插入更方便

    在线工具 一.Sql Server插入方案介绍 关于 SqlServer 批量插入的方式,有三种比较常用的插入方式,Insert.BatchInsert.SqlBulkCopy,下面我们对比以下三种方 ...

  5. Mybatis批量插入数据的两种方式

    总体描述 软件开发过程中需要批量插入数据的场景有几种: 从离线文件(excel, csv等)导入大批量数据到系统. 从其它系统定时或者人工同步大批量数据到系统. 程序自身的某些算法执行时会生成大批量数 ...

  6. MyBatis 批量插入数据的 3 种方法

    批量插入功能是我们日常工作中比较常见的业务功能之一,之前我也写过一篇关于<MyBatis Plus 批量数据插入功能,yyds!>的文章,但评论区的反馈不是很好,主要有两个问题:第一,对 ...

  7. MySQL批量插入数据的几种方法

    最近公司要求测试数据库的性能,就上网查了一些批量插入数据的代码,发现有好几种不同的用法,插入同样数据的耗时也有区别 别的先不说,先上一段代码与君共享 方法一: package com.bigdata; ...

  8. Mybatis的批量插入数据库的两种方法及代码自动生成工具的使用方法

    文章目录 常规批量插入.(通过foreach,生成很长的SQL) ExecutorType.BATCH方式执行批量操作 在这里简单介绍一下,自动生成工具的使用方法 常规批量插入.(通过foreach, ...

  9. 数据库批量插入数据的三种方法

    一.准备工作 测试环境:SpringBoot项目+MybatisPlus框架+MySQL数据库+Lombok 二.导入依赖 <dependency><groupId>org.s ...

  10. MySQl数据库-批量添加数据的两种方法

    当你需要往数据表中添加数据,如果少量,手动添加其实没什么问题.但是当你需要测试大量数据时,比如要统计一年.一个月.一个星期的数据的区别,而且需求是必须每天都要有数据,这时就需要批量添加数据.在这里以u ...

最新文章

  1. LeetCode简单题之检查某单词是否等于两单词之和
  2. Online Judge上陪审团选人问题用Java实现的一个AC解
  3. iOS代码编程规范 根据项目经验汇总
  4. 以supervisord启动elasticsearch
  5. python修改excel后打印_python 处理excel并打印excel
  6. 欧几里得算法(即辗转相除法)的时间复杂度
  7. 使用Docker,Chef和Amazon OpsWorks进行集群范围的Java / Scala应用程序部署
  8. 隐藏自己电脑的IP地址
  9. 请MVC5 WebApi2 支持OData协议查询
  10. 使用正则表达是搜索多个字符串,表达式中加入变量
  11. hdu 2528:Area(计算几何,求线段与直线交点 + 求多边形面积)
  12. 001-开发环境及其基本常识
  13. 【MySQL】时间格式转换 DATE_FORMAT函数篇
  14. 吊打面试官之redis篇:一文全懂redis
  15. JDBC连接池原理及分析
  16. 宇视监控摄像头使用什么工具批量修改IP地址
  17. 老九课堂c语言百度云,老九学堂C语言
  18. 1.认识华为数据通信
  19. FINN(二)CNN,BNN及其硬件实现的背景知识
  20. 比尔盖茨的十大经典人生定律

热门文章

  1. 《你必须知道的.NET》书中对OCP(开放封闭)原则的阐述
  2. 将object类型转换成时间,如果能转的话。
  3. 百篇论文分类整理看数据增广最新研究进展
  4. 搜索系统中的纠错问题
  5. 【MLNLP顶会论文发表总榜】谷歌最狂,清北入前十,周明、张岳、刘挺华人前三,中美差距何止一点点!...
  6. 干货 | 140页《深度强化学习入门》
  7. 授人以渔:分享我的文本分类经验总结
  8. 腾讯看点CTO徐羽: QQ浏览器背后的推荐AI中台 | AICon
  9. 深度探索C++对象模型
  10. IT项目管理之系统规划