我有一些代码,在程序结束时,将6个不同列表的全部内容上传到数据库中。问题是,它们是并行列表,每个列表中有大约14,000个项目,我必须为每个单独的项目运行一个Insert查询。这需要很长时间,有更快的方法吗?以下是相关代码的示例:
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();
}
以下是代码从配置文件中提取的命令字符串:
CommandString中:
INSERT dbo.InternetUsage VALUES (@user, @computer, @date, @itemName, @itemDetails, @timesUsed)
答案 0 :(得分:2)
答案 1 :(得分:2)
如@ alerya的回答所述,执行以下操作将有所帮助(此处添加说明)
1)在for循环之外创建命令和参数 由于每次都使用相同的命令,因此每次重新创建命令都没有意义。除了创建一个新对象(需要时间)之外,每次为多个事物(表存在等)创建命令时,还必须验证该命令。这引入了很多开销。
2)将插入内容置于事务中 将所有插入放在事务中会加快速度,因为默认情况下,不在事务中的命令将被视为自己的事务。因此,每次插入内容时,数据库服务器都必须验证它刚插入的内容是否实际保存(通常在硬盘上,受磁盘速度的限制)。但是,当多个INSERT在一个事务中时,只需要执行一次检查。
根据您已经展示过的代码,这种方法的缺点是,一个糟糕的INSERT会破坏这一堆。这是否可以接受取决于您的具体要求。
<强>除了强> 你应该做的另一件事(虽然这不会在短期内加快速度)是正确使用IDisposable接口。这意味着在所有IDisposable对象(SqlConnection,SqlCommand)上调用.Dispose(),或者理想情况下,将它们包装在using()块中:
using( SqlConnection dataConnection = new SqlConnection(cs)
{
//Code goes here
}
这可以防止这些位置的内存泄漏,如果你的循环变得太大,这将很快成为一个问题。
答案 2 :(得分:1)
将INSERT命令逐个发送到数据库将真正使整个过程变慢,因为往返数据库服务器。如果您担心性能,则应考虑使用批量插入策略。你可以:
聚苯乙烯。我猜你说SQL时你正在使用MS SQL Server。
答案 3 :(得分:-1)
为什么不从单独的线程运行 uploadContent()方法。
这样,您无需担心查询执行的时间。