SQL Server一括挿入データ事例詳細
SQL Serverでデータを挿入するにはInsert文を使用しますが、大量のデータを一括して挿入する場合、Insertを周期的に使用すると効率が悪いだけでなく、SQL aシステムのパフォーマンス問題の原因となります。ここでは、SQL Serverがサポートする2つの一括データ挿入方法を紹介します。一括挿入とTVP(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
I. 従来のINSERTアプローチ
まず、従来のINSERTアプローチを見てみましょう。1つずつ挿入していきます(パフォーマンス消費と速度低下が増加します)。
//Insert one by one using the simpleInsert method [slow]
#region [ simpleInsert ]
static void simpleInsert()
{
Console.WriteLine("Insert one bar at a time using the simpleInsert method");
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;
Open();
Open(); try
{
//Insert 1000 pieces of data in a loop, 100 pieces at a time, 10 times.
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();
}
// After every 100,000 data insertions, display the time spent on this insertion
Console.WriteLine(string.Format("Elapsed Time is {0} Milliseconds", sw.ElapsedMilliseconds));
}
Console.ReadKey();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
#endregion
1000件のデータ挿入を100件ずつ10回ループさせると、効率がどんどん悪くなっていきます。
II. より迅速なバルク挿入方法。
一括挿入を利用することで、[ より速く ]。
//Insertion with Bulk [ faster]
#region [ inserted using 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";
BatchSize = dt.Rows;
BatchSize = dt.
{
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("The case of using a simple Bulk insert");
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.ElapsedMilliseInsert 1000 pieces of data cyclically, 100 pieces each time, 10 times, much faster efficiency.
III. Inserting data using the abbreviation TVPs
Open sqlserrver and execute the following script.
--Create Table Valued
CREATE TYPE BulkUdt AS TABLE
(Id int,
UserName nvarchar(32),
Pwd varchar(16))
After success, we found more cache tables for BulkUdt in the database.
Insert data using the abbreviation TVPs
//Insert data using abbreviated TVPs [fastest]
#region [ insert data using abbreviated 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("Inserting data using the abbreviation 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
The efficiency is getting slower and slower when inserting 1000 pieces of data cyclically, 100 pieces each time, 10 times. Later test, increase the amount of data inserted each time, it will reflect the efficiency of TPVS insertion more.
This article about SQL Server batch insert data case is introduced to this, more related SQL Server batch insert data content please search the previous articles of the Codedevlib or continue to browse the following related articles hope you will support the Codedevlib more in the future!
関連
-
あるユーザーの連続ログイン日数を求めるSQLクエリ
-
SQLの書き方--行ごとの比較
-
SQL Server のフィルタードインデックスによるクエリ文の改善に関するパフォーマンス分析
-
SQLServerのエラーです。15404, unable to get information about Windows NT group/user WIN-8IVSNAQS8T7Administrator
-
SQLServerにおけるJSONドキュメント型データのクエリ問題を解決する。
-
SQLでのmod()関数の余りの使用法
-
SQL クエリ結果カラムのカンマ区切り文字列へのステッチング法
-
SQL SERVERオープンCDC実践講座詳細
-
データベース毎日練習問題、毎日少しづつ進歩(1)
-
データベース毎日練習問題、毎日少しづつ進歩(2)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Windows環境でのSqlファイルの一括実行
-
SQL Server 2017がサーバーに接続できない問題解決
-
SQLSERVER 変数文字列を用いたスプライシング ケース詳細
-
MySQLスレーブ遅延1列外部キーチェックとセルフインクリメントロック
-
mybatis動的SQL実装ロジックコード詳細
-
mybatis動的SQLの共通シナリオのまとめ
-
NavicatはSQL Serverのデータに接続します。エラー08001に対する完璧な解決策 - Named Pipeline Provider
-
日付で年齢を判定するSQLサンプルコード 関数
-
SQLスキルのデータベースは、ケースを整理する
-
SQL SERVERのコミット・トランザクションのロールバック機構