SQL Server批量插入數(shù)據(jù)案例詳解
在SQL Server 中插入一條數(shù)據(jù)使用Insert語句,但是如果想要批量插入一堆數(shù)據(jù)的話,循環(huán)使用Insert不僅效率低,而且會(huì)導(dǎo)致SQL一系統(tǒng)性能問題。下面介紹SQL Server支持的兩種批量數(shù)據(jù)插入方法:Bulk和表值參數(shù)(Table-Valued Parameters),高效插入數(shù)據(jù)。
新建數(shù)據(jù)庫(kù):
--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
一.傳統(tǒng)的INSERT方式
先看下傳統(tǒng)的INSERT方式:一條一條的插入(性能消耗越來越大,速度越來越慢)
//使用簡(jiǎn)單的Insert方法一條條插入 [慢] #region [ simpleInsert ] static void simpleInsert() { Console.WriteLine("使用簡(jiǎn)單的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 { //循環(huán)插入1000條數(shù)據(jù),每次插入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萬條數(shù)據(jù)后,顯示此次插入所用時(shí)間 Console.WriteLine(string.Format("Elapsed Time is {0} Milliseconds", sw.ElapsedMilliseconds)); } Console.ReadKey(); } catch (Exception ex) { Console.WriteLine(ex.Message); } } #endregion
循環(huán)插入1000條數(shù)據(jù),每次插入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("使用簡(jiǎn)單的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
循環(huán)插入1000條數(shù)據(jù),每次插入100條,插入10次,效率快了很多。
三.使用簡(jiǎn)稱TVPs插入數(shù)據(jù)
打開sqlserrver,執(zhí)行以下腳本:
--Create Table Valued CREATE TYPE BulkUdt AS TABLE (Id int, UserName nvarchar(32), Pwd varchar(16))
成功后在數(shù)據(jù)庫(kù)中發(fā)現(xiàn)多了BulkUdt的緩存表。
使用簡(jiǎn)稱TVPs插入數(shù)據(jù)
//使用簡(jiǎn)稱TVPs插入數(shù)據(jù) [最快] #region [ 使用簡(jiǎn)稱TVPs插入數(shù)據(jù) ] 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("使用簡(jiǎn)稱TVPs插入數(shù)據(jù)"); 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
循環(huán)插入1000條數(shù)據(jù),每次插入100條,插入10次,效率是越來越慢,后面測(cè)試,將每次插入的數(shù)據(jù)量增大,會(huì)更大的體現(xiàn)TPVS插入的效率。
到此這篇關(guān)于SQL Server批量插入數(shù)據(jù)案例詳解的文章就介紹到這了,更多相關(guān)SQL Server批量插入數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解鎖?SQL?Server?2022的時(shí)間序列數(shù)據(jù)功能(示例詳解)
SQL?Server2022在處理時(shí)間序列數(shù)據(jù)時(shí),SQL?Server?提供了一些優(yōu)化和功能,比如?DATE_BUCKET?函數(shù)、窗口函數(shù)以及其他時(shí)間日期函數(shù),以便更高效地處理時(shí)間序列數(shù)據(jù),這篇文章主要介紹了解鎖?SQL?Server?2022的時(shí)間序列數(shù)據(jù)功能,需要的朋友可以參考下2024-08-08SQL Server查詢數(shù)據(jù)庫(kù)中表使用空間信息實(shí)現(xiàn)腳本
這篇文章主要介紹了SQL Server查詢數(shù)據(jù)庫(kù)中表使用空間信息實(shí)現(xiàn)腳本,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-07-07windows無法停止SQLserver 服務(wù)的強(qiáng)制關(guān)閉進(jìn)程方案(強(qiáng)制重啟sqlserver Pol
今天在配置sqlserver需要重啟的時(shí)候,提示其它服務(wù)也需要重啟,但SQL Server PolyBase 數(shù)據(jù)移動(dòng) (MSSQLSERVER)無法重啟了,這里就給出終極解決方法,強(qiáng)制關(guān)閉PolyBase 數(shù)據(jù)移動(dòng)進(jìn)程,再重啟sqlserver就可以了2024-03-03t-sql/mssql用命令行導(dǎo)入數(shù)據(jù)腳本的SQL語句示例
這篇文章主要介紹了t-sql或mssql用命令行導(dǎo)入數(shù)據(jù)腳本的SQL語句示例,大家參考使用吧2013-11-11Sql Server中判斷表、列不存在則創(chuàng)建的方法
這篇文章主要給大家分享了Sql Server中判斷表、列是否存在,如果不存在則創(chuàng)建的方法,文章先給大家簡(jiǎn)單介紹了Sql Server中判斷表中某列是否存在的方法,文中給出了詳細(xì)的示例代碼,需要的朋友們可以參考借鑒,下面來一起看看吧。2017-03-03淺談基于SQL Server分頁存儲(chǔ)過程五種方法及性能比較
本文由腳本之家小編給大家分享了五種sqlserver分頁存儲(chǔ)過程及性能比較,接下來我們跟著小編一起了解了解吧2015-09-09SQL?Server?字段設(shè)自增的實(shí)現(xiàn)流程
這篇文章主要介紹了SQL?Server?字段設(shè)自增的實(shí)現(xiàn)方法,在本文中,我將先向你展示整個(gè)實(shí)現(xiàn)的流程,然后逐步解釋每個(gè)步驟需要做什么,并提供相應(yīng)的代碼示例,需要的朋友可以參考下2023-12-12