我在Windows服务中每天处理大约24k条记录,我将行插入数据库,然后将压缩的图像保存在目录中。
一般来说,最好的方法是什么?
using (SqlConnection cnn = new SqlConnection())
{
foreach (var item in collection)
{
//do stuff
SaveImage(item.filename,item.img);
}
}
或
foreach (var item in collection)
{
using (SqlConnection cnn = new SqlConnection())
{
//do stuff
}
SaveImage(item.filename, item.img);
}
由于
答案 0 :(得分:2)
我会在循环之外构建连接。如果它是永远运行的东西我的答案会有所不同,例如,如果您运行的是Web服务,我建议您为每个请求打开连接(这是非常不同的,但是我只是举个例子)。但是打开一个连接是一项资源密集型任务,在这种情况下,它可以更容易地处理单个连接。这真的取决于你在这里关注的内容,正如其他几个人所说,但我认为单个连接听起来完全可以接受。正如我看到另一位评论者所说的那样,你可以使用交易将其全部包起来,如果这对你有帮助的话。
其余的这些东西并不意味着直接回答你的问题,我认为考虑到你的情况,它值得考虑。
但是,您可能希望查看SQL MERGE
语句。如果您可以一次向SQL发送多条记录,速度会快得多。当然,您仍然必须单独保存图像,但这至少可以使SQL方面更快。当然,您也可以使用INSERT
声明执行此操作,但这取决于您传递的每条新记录是否真的是新的,或者是否违反了唯一键。
您还可以查看TPL Dataflow,因为它有一些有用的类可以同时执行多个操作,并且批量生成也可以使插入方式更快。但请记住,单个连接有时不是处理并发请求的最佳选择。但是如果你将数据分成100组(请记住,2100是每SqlCommand
个查询参数的最大数量,所以只需要按照你需要的数量除以并减去误差幅度),我&#39 ; d可能只是说为每个人创建连接。
我知道这比你要求的更多,但是我经常处理这样的情况,所以我想我会分享一些我在路上所接受的东西。
答案 1 :(得分:0)
答案 2 :(得分:0)
这里有很多因素,但在大多数情况下,我建议在循环中打开/关闭连接,并根据需要在连接期间使用数据库。
您需要进行大量的错误处理,但如果在连接或图像处理过程中出现问题,则可以更轻松地继续循环以获取更多记录。
答案 3 :(得分:0)
如果连接中断,您的第一种方法将跳过整个过程。
你的第二种方法是在EACH循环上创建一个新的连接,这很糟糕地降低了性能。
你可以做的是批量执行(比如50)。
var batchSize = 50;
for(int i = 0; i<collection.Count ; i+=batchSize)
{
using (var cnn = new SqlConnection())
{
int j = 0
foreach (var item in collection.Skip(i))
{
if(j++ == batchSize) continue;
//do stuff
SaveImage(item.filename,item.img);
}
}
}
在这里,您每50行创建一次连接数据。您可以根据自己的意愿进行调整,以优化性能与可靠性。