处理连接/查询的最佳实践

3

关于C#最佳实践的问题。我有一个类,它迭代遍历5000个对象,并为每个对象调用后端:

运行循环的类:

for(Object x in objects) //5000
{
   nonStaticObject.callThisMethod(x.id);
}

DAL layer:

ReturnObject x = null;
using(SQLConnection...)
{
    using(SQLCommand...)
    {
         // run something here
         // if found, instantiate object x
    }
}

由于我的代码(并行for循环)产生了一些高CPU,我进行了一些分析,热点似乎是(也应该是)我所做的所有数据库调用。由于这些调用非常频繁,我有一些问题。

在我看来,我的想法是如果可能的话应该重复使用连接。这是最佳实践吗?我想允许代码处理连接释放(使用using关键字),如何设置一个对所有5000个调用都可用的有效连接策略?我现在是否应该像现在这样每次调用该方法时创建一个连接?(我在某个地方读到过ADO连接池自动重用连接,所以这可能已经在后台完成了?)

感谢任何帮助


是实际调用数据库的代码出了问题,还是与其相关的代码?尝试在一侧使用.NET分析器,然后使用SQL分析器并比较结果。根据我的经验,在使用数据库时,大部分时间都花在等待结果上。这就是为什么将多个查询合并成一个有所帮助的原因。 - Victor Zakharov
SQL Profiler没有显示任何值得担心的内容。已经建立的索引是有效和快速的。我认为这可能是因为我正在建立大量的连接?所有5000个连接在30秒内都被处理完毕,所以这是一个短时间内的5000个连接请求(如果这很重要的话)。 - user2124871
你的连接不必经常释放。只要你在使用它们,就可以让它保持打开状态。你必须考虑事务,而不是连接。但问题可能在于迭代本身。我仍然无法弄清楚上面的代码与下面的代码有何关系。 - rodrigogq
如果您能够提供更多的代码,那将会有所帮助,因为现在您的解释对我们来说还是比较抽象的,很难给出具体的建议(除了@Habib在下面回答中提到的)。也许可以尝试用类比的方式来简单地解释您的过程。 - Victor Zakharov
1个回答

4
通常情况下,对于数据库连接,策略应该尽可能晚地打开并尽早关闭。因此,假设您只有一个要执行的单个语句/查询,则在执行查询之前打开连接,并在此之后关闭连接。
但是,在您的情况下,您正在循环中执行5000个查询,因此没有必要5000次打开/关闭连接。相反,利用单个连接并执行所有查询。
此外,打开和关闭连接只会将连接返回到.Net连接池中。如果已经存在一个打开的连接,则使用Conn.Open();打开连接将从连接池中返回打开的连接。请参见:SQL Server Connection Pooling (ADO.NET)Creating database connections - Do it once or for each query?

在我的情况下,我有一个使用方法生成向数据库发送请求的DAL对象,那么在进行5000次调用之前,我该如何使用连接池来打开连接呢?通常情况下,我会使用using() {...}的过程来实现这一点(我怀疑在当前设置中无法做到)。非常感谢您的答案 :) - user2124871
@user2124871,将你的集合传递给DAL中的一个方法,在using语句中设置你的连接,并在其中执行循环,这样每个项目都会使用相同的连接。 - Habib
1
好的,这正是我想到的。再次感谢你的提示。 - user2124871

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接