SqlBulkCopy のベンチマーク
.NET 2.0 で、大量のデータをインポートするクラス SqlBulkCopy が導入された。その性能を試してみたのでメモ。
テスト結果
試行したPCの性能は以下のとおり。
CPU : Pen4 2.4GHz , RAM : 512MB , OS : WinXPSP2 , DB : SQLServer 2005 Express
各データ数に対して連続で5回試行し、その平均をとってみた。
データ数 SqlCommand SqlBulkCopy 100 : 108.6 [ms] 15.0 [ms] 1000 : 990.2 [ms] 80.6 [ms] 10000 : 7999.6 [ms] 193.4 [ms] 100000 : 75634.0 [ms] 1696.4 [ms]
1000件くらいなら1件ずつINSERTでも我慢できないレベルじゃないけど、1万件を超えると迷わず SqlBulkCopy を使えという感じかな。残念なのは、クラス名が示すように SQLServer 用にしか用意されていないこと。
テストコード
前半は SqlCommand を使って Table1 に1件ずつ INSERT している。
後半では、Table1 からデータを DataTable に抽出して SqlBulkCopy で Table2 にインポートしている。
string constr = @"Data Source=.\sqlexpress;Initial Catalog=testdb;Integrated Security=True"; using (SqlConnection con = new SqlConnection(constr)) { con.Open(); SqlCommand c = new SqlCommand("INSERT INTO Table1 VALUES(@id,@name)", con); c.Parameters.Add("@id", SqlDbType.Int); c.Parameters.Add("@name", SqlDbType.NVarChar); DateTime start = DateTime.Now; for (int i = 1; i <= COUNT; i++) { c.Parameters["@id"].Value = i; c.Parameters["@name"].Value = "name"; c.ExecuteNonQuery(); } TimeSpan span = DateTime.Now - start; Log(span, true); } DataTable table = new DataTable(); using (SqlConnection con = new SqlConnection(constr)) { con.Open(); SqlCommand command = new SqlCommand("SELECT * FROM Table1", con); SqlDataAdapter adapter = new SqlDataAdapter(command); adapter.Fill(table); } using (SqlConnection con = new SqlConnection(constr)) { con.Open(); using (SqlBulkCopy copy = new SqlBulkCopy(con)) { copy.DestinationTableName = "Table2"; DateTime start = DateTime.Now; copy.WriteToServer(table); TimeSpan span = DateTime.Now - start; Log(span, false); } }