我在启动Windows服务时遇到了一些性能问题,第一轮我的lstSps很长(大约130个存储过程)。无论如何都要加快速度(除了加快存储过程的速度)?
当foreach结束并进入第二轮时,它会更快,因为在TimeToRun()上没有多少返回true。但是,我关注的是第一次,当有更多的存储过程要运行时。
我有关于创建一个数组和一个for循环,因为我读得更快,但我相信问题是因为这些过程需要很长时间。我可以用更好的方式构建它吗?也许使用多个线程(每个执行一个)或类似的东西?
非常感谢一些提示:)
编辑:只是为了澄清一下,它的方法HasResult()正在执行SP:s并且看起来需要时间......
lock (lstSpsToSend)
{
lock (lstSps)
{
foreach (var sp in lstSps.Where(sp => sp .TimeToRun()).Where(sp => sp.HasResult()))
{
lstSpsToSend.Add(sp);
}
}
}
while (lstSpsToSend.Count > 0)
{
//Take the first watchdog in list and then remove it
Sp sp;
lock (lstSpsToSend)
{
sp = lstSpsToSend[0];
lstSpsToSend.RemoveAt(0);
}
try
{
//Send the results
}
catch (Exception e)
{
Thread.Sleep(30000);
}
}
答案 0 :(得分:1)
我会做的是这样的事情:
int openThread = 0;
ConcurrentQueue<Type> queue = new ConcurrentQueue<Type>();
foreach (var sp in lstSps)
{
Thread worker = new Thread(() =>
{
Interlocked.Increment(ref openThread);
if(sp.TimeToRun() && sp.HasResult)
{
queue.add(sp);
}
Interlocked.Decrement(ref openThread);
}) {Priority = ThreadPriority.AboveNormal, IsBackground = false};
worker.Start();
}
// Wait for all thread to be finnished
while(openThread > 0)
{
Thread.Sleep(500);
}
// And here move sp from queue to lstSpsToSend
while (lstSpsToSend.Count > 0)
{
//Take the first watchdog in list and then remove it
Sp sp;
lock (lstSpsToSend)
{
sp = lstSpsToSend[0];
lstSpsToSend.RemoveAt(0);
}
try
{
//Send the results
}
catch (Exception e)
{
Thread.Sleep(30000);
}
}
答案 1 :(得分:0)
最好的方法很大程度上依赖于这些存储过程实际执行的操作,如果它们返回相同类型的结果集,或者没有结果,那么将它们一次性发送到SQL服务器肯定是有益的而不是一次一个。
原因是网络延迟,如果您的SQL服务器位于您通过WAN访问的某个数据中心,您的延迟可能会超过200毫秒。因此,如果你按顺序调用130个存储过程,那么“cost”将是200ms X 130.这是26秒,只是通过网络连接来回运行而不是实际执行proc中的逻辑。
如果您可以将所有程序合并为一个电话,则只需支付200毫秒的费用。
在多个并发线程上执行它们也是一种合理的方法,但与以前一样,它取决于您的程序正在做什么并返回给您。
在列表上使用数组并不能真正提高性能。
希望这有帮助,祝你好运!