在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次,效率是越来越慢。
二.较快速的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次,效率快了很多。
三.使用简称tvps插入数据
打开sqlserrver,执行以下脚本:
--create table valued create type bulkudt as table (id int, username nvarchar(32), pwd varchar(16))
成功后在数据库中发现多了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
循环插入1000条数据,每次插入100条,插入10次,效率是越来越慢,后面测试,将每次插入的数据量增大,会更大的体现tpvs插入的效率。
到此这篇关于sql server批量插入数据案例详解的文章就介绍到这了,更多相关sql server批量插入数据内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!