[转载]SQLServer 批量插入数据的两种方法。

在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 --Create Table Valued CREATE TYPE BulkUdt AS
TABLE (Id int, UserName nvarchar(32), Pwd varchar(16))

下面我们使用最简单的Insert语句来插入100万条数据,代码如下: 复制代码 代码如下: Stopwatch sw = new
Stopwatch();

SqlConnection sqlConn = new SqlConnection(
ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString);//连接数据库

SqlCommand sqlComm = new SqlCommand(); sqlComm.CommandText =
string.Format("insert into
BulkTestTable(Id,UserName,Pwd)values(@p0,@p1,@p2)");//参数化SQL
sqlComm.Parameters.Add("@p0", SqlDbType.Int); sqlComm.Parameters.Add("@p1",
SqlDbType.NVarChar); sqlComm.Parameters.Add("@p2", SqlDbType.VarChar);
sqlComm.CommandType = CommandType.Text; sqlComm.Connection = sqlConn;
sqlConn.Open(); try { //循环插入100万条数据,每次插入10万条,插入10次。 for (int multiply = 0;
multiply < 10; multiply++) { for (int count = multiply * 100000; count <
(multiply + 1) * 100000; count++) {

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

Console.ReadLine();

耗时图如下:

使用Insert语句插入10万数据的耗时图

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

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

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

代码如下:

复制代码 代码如下: public static void BulkToDB(DataTable dt) { SqlConnection sqlConn
= new SqlConnection(
ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString); 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) { throw ex; } finally { sqlConn.Close(); if (bulkCopy != null)
bulkCopy.Close(); } }

public 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 Main(string[] args) { Stopwatch sw = new Stopwatch(); for (int
multiply = 0; multiply < 10; multiply++) { DataTable dt =
Bulk.GetTableSchema(); for (int count = multiply * 100000; count < (multiply
+ 1) * 100000; 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(); Bulk.BulkToDB(dt); sw.Stop();
Console.WriteLine(string.Format("Elapsed Time is {0} Milliseconds",
sw.ElapsedMilliseconds)); }

Console.ReadLine(); }

耗时图如下: 使用Bulk插入100万数据的耗时图

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

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

表值参数是SQL Server 2008新特性,简称TVPs。对于表值参数不熟悉的朋友,可以参考最新的book
online,我也会另外写一篇关于表值参数的博客,不过此次不对表值参数的概念做过多的介绍。言归正传,看代码: 复制代码 代码如下: public static
void TableValuedToDB(DataTable dt) { SqlConnection sqlConn = new SqlConnection(
ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString); 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; //表值参数的名字叫BulkUdt,在上面的建立测试环境的SQL中有。 catParam.TypeName =
"dbo.BulkUdt"; try { sqlConn.Open(); if (dt != null && dt.Rows.Count !=
0) { cmd.ExecuteNonQuery(); } } catch (Exception ex) { throw ex; } finally {
sqlConn.Close(); } }

public 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 Main(string[] args) { Stopwatch sw = new Stopwatch(); for (int
multiply = 0; multiply < 10; multiply++) { DataTable dt =
TableValued.GetTableSchema(); for (int count = multiply * 100000; count <
(multiply + 1) * 100000; 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();
TableValued.TableValuedToDB(dt); sw.Stop();
Console.WriteLine(string.Format("Elapsed Time is {0} Milliseconds",
sw.ElapsedMilliseconds)); }

Console.ReadLine(); }

耗时图如下:

使用表值参数插入100万数据的耗时图

比Bulk还快5秒。

详细出处参考:http://blog.csdn.net/tjvictor/article/details/4360030

时间: 2024-08-06 07:35:43

[转载]SQLServer 批量插入数据的两种方法。的相关文章

SQL Server 批量插入数据的两种方法

在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数据的话,循环使用Insert不仅效率低,而且会导致SQL一系统性能问题.下面介绍SQL Server支持的两种批量数据插入方法:Bulk和表值参数(Table-Valued Parameters). 运行下面的脚本,建立测试数据库和表值参数. [c-sharp] view plaincopy --Create DataBase create database BulkTestDB; go use BulkTes

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

在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数据的话,循环使用Insert不仅效率低,而且会导致SQL一系统性能问题.下面介绍SQL Server支持的两种批量数据插入方法:Bulk和表值参数(Table-Valued Parameters). 运行下面的脚本,建立测试数据库和表值参数. [c-sharp] view plaincopy --Create DataBase create database BulkTestDB; go use BulkTes

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

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

用python代码简单连接MySQL以及插入数据的两种方法

连接MySQL代码如下: import pymysql # 打开数据库连接 参数依次如下: conn = pymysql.connect(host='localhost',user='root',password='1234',database='pymysql_demo',port=3306) # 使用cursor()方法获取操作游标 cursor = conn.cursor() . . . . # 关闭数据库连接 conn.close() 插入数据: 1) import pymysql co

mysql大批量插入数据的4种方法示例

前言 本文主要给大家介绍了关于mysql大批量插入数据的4种方法,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 方法一:循环插入 这个也是最普通的方式,如果数据量不是很大,可以使用,但是每次都要消耗连接数据库的资源. 大致思维如下 (我这里写伪代码,具体编写可以结合自己的业务逻辑或者框架语法编写) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 for($i=1;$i<=100;$i++){  $sql = 'insert...............';  /

MySQL中删除数据的两种方法

转自:http://blog.csdn.net/apache6/article/details/2778878 在MySQL中有两种方法可以删除数据,一种是DELETE语句,另一种是TRUNCATE TABLE语句. DELETE语句可以通过WHERE对要删除的记录进行选择.而使用TRUNCATE TABLE将删除表中的所有记录.因此,DELETE语句更灵活. 如果要清空表中的所有记录,可以使用下面的两种方法: DELETE FROM table1 TRUNCATE TABLE table1 其

DataGridView显示数据的两种方法

1.简单介绍 DataGridView空间是我们常用的显示数据的控件,它有极高的可配置性和可扩展性. 2.显示数据 DataGridView显示数据一般我们常用的有两种方法,一种是直接设置DataSoure属性就可以绑定数据.此方法不需要写任何代码操作比较简单,但是它显示出来的是整张表的数据.如果整一表数据比较多,而且我们并不需要所有的数据的情况下,我们就应该考虑第二种方法了.通过写代码连接数据库并从数据库中读取数据,最后将返回的数据传给DataGridView.这种方法貌似比较复杂,但是它只显

SpringMVC中controller返回json数据的两种方法

SpringMVC中controller返回json数据的两种方法 1.jsp的ajax请求: function getJson(){ $.ajax({ type:"get", dataType:"json", url:"<%=basePath %>getJson", success:function(data){ for(var i=0;i<jsonData.length;i++){ alert("Id:"

Java构造和解析Json数据的两种方法详解一

原文链接:http://www.cnblogs.com/lanxuezaipiao/archive/2013/05/23/3096001.html 在www.json.org上公布了很多Java下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面首先介绍用json-lib构造和解析Json数据的方法示例. 用org.son构造和解析Json数据的方法详解请参见我下一篇博文:Java构造和解析Json数据的两种方法详解二 一.介绍 JSO