此代码序列化整数数组,然后将其插入到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 :(得分:10)
我建议你把这个功能分成两部分。一个关于字节数组,另一个关于插入数据库。
然后运行分析,看看字节数组代码是否很慢或者是否是数据库问题。
也许你正试图加速一些不慢的东西:)
答案 1 :(得分:6)
如果要插入大量行,SqlBulkCopy
类比调用insert
很多次要快得多。请参阅此blog post for an example。
答案 2 :(得分:1)
我要尝试的第一件事是为内存流预先分配byte[]
:
var array = new int[BitConverter.GetBytes(0).Length * items.Length];
using (MemoryStream stream = new MemoryStream(array))
{
// ... rest is almost the same
}
答案 3 :(得分:1)
您可以使用insert命令创建一个过程。它更快,因为已经为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
中看到更多内容答案 4 :(得分: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
一次一个地提取字节并将它们放在缓冲区中。然后将缓冲区写入流。另一方面,BitConverter
每次调用时都会分配一个新的4字节缓冲区。