我有一些代码,在程序生命周期结束时,将 6 个不同列表的全部内容上传到数据库中。问题是,它们是并行列表,每个列表约有 14,000 个项目,我必须为每个单独的项目运行插入查询。这需要很长时间,有没有更快的方法?下面是相关代码的示例:
public void uploadContent()
{
var cs = Properties.Settings.Default.Database;
SqlConnection dataConnection = new SqlConnection(cs);
dataConnection.Open();
for (int i = 0; i < urlList.Count; i++)
{
SqlCommand dataCommand = new SqlCommand(Properties.Settings.Default.CommandString, dataConnection);
try
{
dataCommand.Parameters.AddWithValue("@user", userList[i]);
dataCommand.Parameters.AddWithValue("@computer", computerList[i]);
dataCommand.Parameters.AddWithValue("@date", timestampList[i]);
dataCommand.Parameters.AddWithValue("@itemName", domainList[i]);
dataCommand.Parameters.AddWithValue("@itemDetails", urlList[i]);
dataCommand.Parameters.AddWithValue("@timesUsed", hitsList[i]);
dataCommand.ExecuteNonQuery();
}
catch (Exception e)
{
using (StreamWriter sw = File.AppendText("errorLog.log"))
{
sw.WriteLine(e);
}
}
}
dataConnection.Close();
}
这是代码从配置文件中提取的命令字符串:
命令字符串:
INSERT dbo.InternetUsage VALUES (@user, @computer, @date, @itemName, @itemDetails, @timesUsed)
最佳答案
正如 @alerya 的回答中提到的,执行以下操作会有所帮助(此处添加解释)
1) 在 for 循环之外创建命令和参数 由于每次都使用相同的命令,因此每次都重新创建该命令是没有意义的。除了创建新对象(这需要时间)之外,每次为多个事物(表存在等)创建命令时还必须验证该命令。这会带来大量开销。
2) 将插入放入事务中 将所有插入放入事务中将加快速度,因为默认情况下,不在事务中的命令将被视为其自己的事务。因此,每次插入内容时,数据库服务器都必须验证刚刚插入的内容是否确实被保存(通常保存在硬盘上,这受到磁盘速度的限制)。然而,当一个事务中有多个 INSERT 时,只需执行一次检查。
根据您已经展示的代码,这种方法的缺点是一个错误的 INSERT 会破坏一堆内容。这是否可以接受取决于您的具体要求。
旁白 您真正应该做的另一件事(尽管这不会在短期内加快速度)是正确使用 IDisposable 接口(interface)。这意味着要么在所有 IDisposable 对象(SqlConnection、SqlCommand)上调用 .Dispose(),要么理想情况下将它们包装在 using() block 中:
using( SqlConnection dataConnection = new SqlConnection(cs)
{
//Code goes here
}
这将防止这些地方发生内存泄漏,如果循环太大,内存泄漏很快就会成为问题。
关于c# - 更快上传到数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13031362/