如何加速这个C#函数/ SQL插入?

时间:2011-03-30 18:06:25

标签: c# .net sql sql-server

此代码序列化整数数组,然后将其插入到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();
            }
        }
    }

5 个答案:

答案 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字节缓冲区。