2011-03-30 3 views
4

このコードは、整数の配列をシリアル化し、それをSQLテーブルに挿入します。それは私が必要とするほど速くはありません。私はもっ​​と効率的に何かをすることができますか?このC#関数/ SQL挿入を高速化するにはどうすればよいですか?

ありがとうございます!私がしようとするだろう

public void SetItem(long Id, int[] items) 
    { 
     using (MemoryStream stream = new MemoryStream()) 
     { 
      foreach (int d in items) 
      { 
       var bin = BitConverter.GetBytes(d); //Serialize 
       stream.Write(bin, 0, bin.Length); 
      } 
      var array = stream.ToArray(); 

      using (SqlCommand cmd = new SqlCommand("INSERT INTO Items(Id, Item, DateCreated) VALUES (@Id, @binaryValue, @dateCreated)", sqlConnection)) 
      { 
       cmd.Parameters.Add("@binaryValue", SqlDbType.VarBinary, array.Length).Value = array; 
       cmd.Parameters.Add("@Id", SqlDbType.BigInt).Value = Id; 
       cmd.Parameters.Add("@dateCreated", SqlDbType.DateTime2).Value = DateTime.Now; 
       cmd.ExecuteNonQuery(); 
      } 
     } 
    } 
+0

BitStreamを使用するのではなく、MemoryStreamの周りにBinaryWriterをラップしてみましたか?また、最後に配列に変換するので、配列ではなくStreamを使用するのはなぜですか?あなたは既にサイズ(items.Count * 4)を知っています –

+0

sqlConnectionはプライベート変数ですか? – rsbarro

+0

はい、sqlConnectionはprvate変数です。 – user404068

答えて

10

私は2でこの機能を分割することをアドバイス。 1つはバイト配列に関するもので、もう1つはDBへの挿入用です。

次にプロファイリングを実行して、バイト配列コードが遅いのか、それともdbの問題であるのかを確認します。

たぶん、あなたは、あなたがコマンドを挿入して、あなたがプロシージャを作成することができます:)

1

まず最初は、メモリストリームのためのbyte[]の事前割り当てです:

var array = new int[BitConverter.GetBytes(0).Length * items.Length]; 
using (MemoryStream stream = new MemoryStream(array)) 
{ 
    // ... rest is almost the same 
} 
1

を遅くされていない何かを加速しようとしています。手順はすでにSQLの

用にコンパイルされるので、それはより速く、このようなものです:

SqlConnection conn = new SqlConnection(actual_string); 
conn.Open(); 

// Create the command string 
SqlCommand cmd = new SqlCommand("EXEC insert_test @var1, @var2, @var3, @str1, @str2", conn); 

// Iterate through all of the objects 
try { 
    for (int i = 0; i < 10000; i++) { 
     cmd.Parameters.Clear(); 
     cmd.Parameters.Add(new SqlParameter("@var1", var1)); 
     cmd.Parameters.Add(new SqlParameter("@var2", var2)); 
     cmd.Parameters.Add(new SqlParameter("@var3", var3)); 
     cmd.Parameters.Add(new SqlParameter("@str1", str1)); 
     cmd.Parameters.Add(new SqlParameter("@str2", str2)); 

     // Read in all the data 
     cmd.ExecuteNonQuery(); 
    } 
} finally { 
    conn.Close(); 
} 

しかし、私の好みはプロシージャにXMLを送信することです。

あなたは、多数の行を挿入している場合は、このgood article

6

でより多くを見ることができ、SqlBulkCopyクラスには多くの時間insertを呼び出すよりもはるかに高速です。このblog post for an exampleを参照してください。

+0

私はこのアプローチも好きです。 –

+0

uhm ...彼は1つの挿入物をdoindしています – BlackTigerX

1

私の最初の傾きがMemoryStreamで使用する事前に割り当てる配列とすること、および、それへの書き込みにBinaryWriterを使用します。

var OutputArray = new byte[items.Length * 4]; 
using (var ms = new MemoryStream(OutputArray)) 
{ 
    using (var writer = new BinaryWriter(ms)) 
    { 
     foreach (var i in items) 
     { 
      writer.Write(i); 
     } 
    } 
} 
// You can now send the OutputArray to SQL server 

BinaryWriterは内部BitConverter.GetBytesを使用していません。むしろ、intから一度に1つずつバイトを抽出し、それらをバッファに入れます。次に、バッファがストリームに書き込まれます。一方、BitConverterは、呼び出すたびに新しい4バイトバッファを割り当てます。

+0

これは少し速いです、ありがとう – user404068

関連する問題