我有一个多线程的Windows应用程序,使用更多的后台工作程序。每个后台工作者都使用一些代码来更新相同的SQL Server数据库,完成后再次运行。我注意到每个后台工作者都在使用单个连接。我创建了一个自定义类的ConcurrentQueue来向其添加所有存储过程并从单个backgorundworker执行它以仅使用一个连接,因为数据库在使用许多连接时变得非常慢。
这是我的代码
这是存储过程类
string _procName;
Dictionary<string, object> _parameters;
public string ProcName
{
get { return _procName; }
set { _procName = value; }
}
public Dictionary<string, object> Parameters
{
get { return _parameters; }
set { _parameters = value; }
}
public PSCProc(string procName, Dictionary<string, object> parameters)
{
_procName = procName;
_parameters = parameters;
}
这是用于运行存储过程的方法
public static void execProc(string procName, Dictionary<string, object> parameters)
{
using (var conn = new SqlConnection(Test.Properties.Settings.Default.testConnection))
using (var command = new SqlCommand(procName, conn)
{
CommandType = CommandType.StoredProcedure
})
{
foreach (var item in parameters)
{
command.Parameters.AddWithValue(item.Key, item.Value);
}
conn.Open();
command.ExecuteNonQuery();
conn.Close();
Form1.updated++;
}
}
这就是我如何将一个项目添加到队列
Dictionary<string, object> parameters = new Dictionary<string, object>();
int x = 1;
string address = "cairo";
parameters.Add("@id", x);
parameters.Add("@address", address);
PSCProc proc1 = new PSCProc("updateAddress", parameters);
pscQueue.Enqueue(proc1);
以及我如何运行后台工作程序来运行程序
PSCProc proc;
if (pscQueue.TryDequeue(out proc))
{
helper.execProc(proc.ProcName, proc.Parameters);
}
请注意: - 执行过程的后台工作程序在完成后再次运行。 - 数据库有太多的锁,因为有数百个使用它。 - 数据库非常重要,无需任何锁即可始终响应。 -connection pooling一直保存睡眠或暂停的连接。 - 将程序添加到队列的比率不会快于执行它们的比率。
我的问题是
使用这种方式更好或使用多个连接不会影响数据库。
答案 0 :(得分:0)
我会创建一个运行存储过程的SQL代理作业。然后您的连接可以登录,启动作业并退出,SQL Agent将在后台运行该作业。这样,在程序运行时,您的连接不会保持打开状态。
话虽这么说,我敢打赌你的数据库并不慢,因为有很多连接,我敢打赌它很慢,因为它代表这些连接运行了很多查询。但是,如果不知道存储过程的代码或模式,就不可能知道。
答案 1 :(得分:0)
连接数量可能会减慢SQL Server的速度,具体取决于实际数量。
减肥的一种方法可以是检查应用程序是否正确使用连接池。为了使其正确,请参阅this MSDN article。很大程度上取决于连接字符串和连接所处的状态。(如果有打开的事务,则不能汇集不同的凭据)
另一种方法是将过程的执行移动到中央服务,并让该服务缓存数据库请求/响应。
最后我要看看程序/查询本身;你提到有很多锁定正在进行中。试着找出原因。您是否在表的末尾创建了插入热点?索引可能有助于删除热点。 (插入)触发器可能会妨碍。 See this post for more details