C# 减少或增加ADO.NET SQL连接,哪个更好?
我有一个多线程的windows应用程序,使用的不仅仅是后台工作程序。每个后台工作人员都在使用一些代码来更新同一个SQL Server数据库,当它完成时,它会再次运行。我注意到每个后台工作人员都使用一个连接。我创建了一个自定义类的ConcurrentQueue,将所有存储过程添加到该类中,并从单个backgorundworker执行该类,以便仅使用一个连接,因为使用多个连接时数据库速度会变得非常慢。 这是我的代码C# 减少或增加ADO.NET SQL连接,哪个更好?,c#,sql-server,multithreading,winforms,ado.net,C#,Sql Server,Multithreading,Winforms,Ado.net,我有一个多线程的windows应用程序,使用的不仅仅是后台工作程序。每个后台工作人员都在使用一些代码来更新同一个SQL Server数据库,当它完成时,它会再次运行。我注意到每个后台工作人员都使用一个连接。我创建了一个自定义类的ConcurrentQueue,将所有存储过程添加到该类中,并从单个backgorundworker执行该类,以便仅使用一个连接,因为使用多个连接时数据库速度会变得非常慢。 这是我的代码 这是存储过程类 string _procName; Dictiona
这是存储过程类
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;
}
请注意:
-执行过程的后台工作进程在完成时再次运行。
-数据库有太多锁,因为有数百个在使用它。
-数据库在没有任何锁的情况下始终保持响应非常重要。
-连接池是保存一直处于休眠或挂起状态的连接。
-将过程添加到队列的比率不会比执行它们的比率快
我的问题是
使用这种方式更好吗?或者使用多个连接不会影响数据库。我会制作一个运行存储过程的SQL代理作业。然后,您的连接可以登录、启动作业并退出,SQL代理将在后台运行作业。这样,在过程运行时,您的连接不会保持打开状态
也就是说,我敢打赌你的数据库不会慢,因为有很多连接,我敢打赌它会慢,因为它代表这些连接运行了很多查询。但是如果不知道存储过程的代码或模式,就真的不可能知道。连接的数量可能会根据实际数量降低SQL Server的速度 一种瘦身的方法是检查应用程序是否正确使用连接池。看看有没有办法把它做好。很大程度上取决于连接字符串和连接所处的状态。(如果存在打开的事务,则不能将不同的凭据合并) 另一种方法是将过程的执行移动到中央服务,并让该服务缓存数据库请求/响应
最后,我将看看过程/查询本身;你提到有很多锁正在进行。试着找出原因。是否在表的末尾创建了插入热点?索引可能有助于删除热点。(插入)触发器可能会妨碍您 为什么不将
SqlCommand
对象排入队列它们已经有了存储存储过程名称和任何必需参数的方法
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);
}